read pixel data from render target in d3d11

TheWind picture TheWind · Nov 20, 2012 · Viewed 8.3k times · Source

I set a texture2d as a device render target. After draw, how can i read and write pixels from render target directly , and present it then.

Answer

Unknown1987 picture Unknown1987 · Feb 20, 2013

If your intent is to use it as an input to another shader: - simply ensure you created the texture2D with the D3D11_BIND_RENDER_TARGET and D3D11_BIND_SHADER_RESOURCE.

  • Bind the texture as render target and render to it.
  • Unbind it as a render target and Bind it as a shader resource and use it in the next shader.
  • Just note that a texture cannot be bound as a target and a resource at the same time.

If your intent is to access the texture on the CPU using C++ as an array of pixels, then you have to do some work. Unfortunately, due to current GPU architectures, it is not possible to directly access a texture2D's pixels since the pixels actually live in GPU memory potential in a special format(swizzled format).

  • Create a texture the GPU can render into.
  • Create a staging texture(D3D11_USAGE_STAGING) that will be used to receive the output of the GPU.
  • Render to the GPU texture.
  • Issue a ID3D11DeviceContext::CopyResource() or ID3D11DeviceContext::CopySubresource()
  • Call ID3D11DeviceContext::Map() on the staging resource to get access to the pixels.
  • Call ID3D11DeviceContext::Unmap() on the staging resource.
  • Call ID3D11DeviceContext::UpdateSubresource() to update the version of the resource the GPU has.

As you can see this is certainly not a trivial set of operations and goes against what the GPU architecture of today is optimized to do. I certainly would not recommend it.

If you do end up going down this path, be sure to also read about all the perf concerns GPU memory read back comes with: http://msdn.microsoft.com/en-us/library/windows/desktop/bb205132(v=vs.85).aspx#Performance_Considerations