[SharpDX] Unable to map a texture to staging buffer

Started by
0 comments, last by SmellyIrishMan 9 years ago

So I'm trying to create an empty texture with a few mip levels, write to that texture using a compute shader, then read those values back to the application. At the moment I have created the texture and my compute shader is running and filling the mips with solid colours. When I try to map the resource though I am not able to read anything.

Here is the basic setup.


Texture2DDescription textureDesc;
textureDesc.Width = 64;
textureDesc.Height = 64;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = SharpDX.DXGI.Format.R16G16B16A16_Float;
textureDesc.SampleDescription.Count = 1;
textureDesc.SampleDescription.Quality = 0;
textureDesc.Usage = ResourceUsage.Default;
textureDesc.BindFlags = BindFlags.UnorderedAccess | BindFlags.ShaderResource;
textureDesc.CpuAccessFlags = CpuAccessFlags.None;
textureDesc.OptionFlags = ResourceOptionFlags.None;
SharpDX.Direct3D11.Texture2D emptyTexture = new SharpDX.Direct3D11.Texture2D(device, textureDesc);

UnorderedAccessViewDescription uavDesc = new UnorderedAccessViewDescription();
uavDesc.Format = SharpDX.DXGI.Format.R16G16B16A16_Float;
uavDesc.Dimension = UnorderedAccessViewDimension.Texture2D;
uavDesc.Texture2D.MipSlice = 0;
UnorderedAccessView uavMip0 = new UnorderedAccessView(device, emptyTexture, uavDesc);

computeShader.SetParameterResource("gOutput", uavMip0);
computeShader.SetParameterValue("fillColour", new Vector4(0.1f, 0.2f, 0.3f, 1.0f));
computeShader.Apply();
device.Dispatch(1, 64, 1);

BufferDescription bufferDesc = new BufferDescription();
bufferDesc.Usage = ResourceUsage.Staging;
bufferDesc.BindFlags = BindFlags.None;
bufferDesc.SizeInBytes = 8 * 64 * 64;
bufferDesc.CpuAccessFlags = CpuAccessFlags.Read;
bufferDesc.StructureByteStride = 8;
bufferDesc.OptionFlags = ResourceOptionFlags.None;
SharpDX.Direct3D11.Buffer localbuffer = new SharpDX.Direct3D11.Buffer(device, bufferDesc);

device.Copy(emptyTexture, 0, localbuffer, 0, SharpDX.DXGI.Format.R16G16B16A16_Float);

DataStream data = new DataStream(8 * 64 * 64, true, true);
DataBox box = ((DeviceContext)device).MapSubresource(localbuffer, MapMode.Read, MapFlags.None, out data);

Half4 value = data.ReadHalf4();

So no matter how many values I read at the end, they're always (0, 0, 0, 0). I'm not really sure where the problem lies at the moment.

Advertisement

Clearly I had some twisted understanding of what I was trying to do.

I finally got D3D debugging working (it's been refusing to work for me the last while) and it clearly said that my destination buffer was the wrong size given the source. Once the debugging information was coming out it was pretty explicit in what I was doing wrong smile.png.


D3D11 ERROR: ID3D11DeviceContext::ResolveSubresource: The SrcSubresource and DstSubresource dimensions are not equal. SrcSubresource = { width:64, height:64, depth:1 }. DstSubresource = { width:32768, height:1, depth:1 }. [ RESOURCE_MANIPULATION ERROR #290: DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID]
D3D11 ERROR: ID3D11DeviceContext::ResolveSubresource: The formats of each Resource are not compatible each other. Source Resource format is (0xa, R16G16B16A16_FLOAT). Destination Resource format is (0, UNKNOWN). [ RESOURCE_MANIPULATION ERROR #292: DEVICE_RESOLVESUBRESOURCE_SOURCE_INVALID]
D3D11 ERROR: ID3D11DeviceContext::ResolveSubresource: Both Resources must be the same Resource type (ie. Texture2D). [ RESOURCE_MANIPULATION ERROR #290: DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID]
D3D11 ERROR: ID3D11DeviceContext::ResolveSubresource: Destination Resource must be a D3D11_USAGE_DEFAULT, without multisampling, and without the BIND_DEPTH_STENCIL flag. The Destination Resource has 1 samples. [ RESOURCE_MANIPULATION ERROR #290: DEVICE_RESOLVESUBRESOURCE_DESTINATION_INVALID]

I had just a simple buffer stream. What I should have been using was another Texture2D only setup for staging. Here is what the fix looks like once I've moved over to using a Texture2D.


Texture2DDescription localBufferDesc = new Texture2DDescription();
localBufferDesc.Width = 64;
localBufferDesc.Height = 64;
localBufferDesc.MipLevels = numOfMips;
localBufferDesc.ArraySize = 1;
localBufferDesc.Format = SharpDX.DXGI.Format.R16G16B16A16_Float;
localBufferDesc.SampleDescription.Count = 1;
localBufferDesc.SampleDescription.Quality = 0;
localBufferDesc.Usage = ResourceUsage.Staging;
localBufferDesc.BindFlags = BindFlags.None;
localBufferDesc.CpuAccessFlags = CpuAccessFlags.Read;
localBufferDesc.OptionFlags = ResourceOptionFlags.None;
SharpDX.Direct3D11.Texture2D localbuffer = new SharpDX.Direct3D11.Texture2D(device, localBufferDesc);

device.Copy(emptyTexture, localbuffer);

DataStream data = new DataStream(8 * 64 * 64, true, true);
DataBox box = ((DeviceContext)device).MapSubresource(localbuffer, 0, 0, MapMode.Read, MapFlags.None, out data);

quickTest = data.ReadHalf4();

This topic is closed to new replies.

Advertisement