Jump to content
  • Advertisement
Sign in to follow this  

[SharpDX] Unable to map a texture to staging buffer

This topic is 1335 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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));
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.


Share this post

Link to post
Share on other sites

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();

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!