[dx10] reading data on cpu from render texture

Started by
5 comments, last by supagu 16 years, 11 months ago
im rendering to a render texture and want to read the pixels on te cpu, for some cpu processing. how ever im having troubles trying to work out which flags i need so here is what im doing:

D3D10_TEXTURE2D_DESC descTex;
descTex.Usage = D3D10_USAGE_DEFAULT;
		descTex.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
		descTex.CPUAccessFlags = 0;
		descTex.MiscFlags = 0;

if (flags & RTF_Write)
		{
			descTex.CPUAccessFlags |= D3D10_CPU_ACCESS_WRITE;
			descTex.Usage = D3D10_USAGE_DYNAMIC;
		}

		if (flags & RTF_Read)
		{
			descTex.CPUAccessFlags |= D3D10_CPU_ACCESS_READ;
			//descTex.Usage = D3D10_USAGE_STAGING;
		}
but spits out this error: D3D10: ERROR: ID3D10Device::CreateTexture2D: A D3D10_USAGE_DEFAULT Resource cannot have any CPUAccessFlags set. The following CPUAccessFlags bits cannot be set in this case: D3D10_CPU_ACCESS_READ (1), D3D10_CPU_ACCESS_WRITE (0). [ STATE_CREATION ERROR #98: CREATETEXTURE2D_INVALIDCPUACCESSFLAGS ] is what im asking possible? seems all usage types return one error or another :(
Advertisement
Right a staging resource could not have any bind point and resources that have bind point cannot make readable from the CPU.

To solve this problem you need two resources. One regular render target that has no CPU access flags and a staging resource that can be read. Every time you want some data back you have to copy the content from the render target to the staging resource. Then you can map the resource and read it. As always it is recommended to have multiple staging resources and use them round robin to avoid stalls while waiting for the GPU.
how does one copy from the render texture to the staging resource?
ID3D10Device::CopyResource or ID3D10Device::CopySubresourceRegion.
Question by your "multiple staging resources and use them round robin":
do you prefer using texture2DArray or an array of texture2Ds? As my former question, which is lower-cost or easy-to-manage? Thanks.

Quote:Original post by Demirug
Right a staging resource could not have any bind point and resources that have bind point cannot make readable from the CPU.

To solve this problem you need two resources. One regular render target that has no CPU access flags and a staging resource that can be read. Every time you want some data back you have to copy the content from the render target to the staging resource. Then you can map the resource and read it. As always it is recommended to have multiple staging resources and use them round robin to avoid stalls while waiting for the GPU.


Quote:Original post by yk_cadcg
do you prefer using texture2DArray or an array of texture2Ds? As my former question, which is lower-cost or easy-to-manage? Thanks.
Well the ultimate goal of the 'round robin' approach is to reduce dependencies and increase seperation between resources being used in different operations.

I would imagine an array of Texture2D's would still be better here as a Texture2DArray has some, even if its just weak, inter-element connections at the API/Driver level.

But that's just a hunch - I've not had enough time with the new technology to know for definite which is the better approach! How about you try them both and let us know? [wink]

Cheers,
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

ID3D10Device::CopyResource
did the trick, thanks guys
:)

for other peoples info:

so i create a normal render texture, if i want to read from it, i create a second staging texture with the following flags:

stagingDescTex.CPUAccessFlags = D3D10_CPU_ACCESS_READ;			stagingDescTex.Usage = D3D10_USAGE_STAGING;			stagingDescTex.BindFlags = 0;


then you can just copy from the render texture to the staging texture. the staging texture can be locked for reading

This topic is closed to new replies.

Advertisement