Sign in to follow this  

Setting render target unbinds textures?

Recommended Posts

Hi, I'm moving my project from Direct3D 9 to Direct3D 11 so I'm learning some new concepts. It seems to me that every time you set a new render target all the previous shader resources are unbinded. Is this the intended behaviour or am I missing somehting?

 

So as an example I render my G-buffer and bind the resulting textures as shader resources, then I go about doing various post processing effects and everytime I set a new render target I need to rebind all the textures from the G-buffer (using PSSetShaderResources). This seems a bit wasteful and I read that binding textures is one of the more expensive operations, so is there a more optimal workflow for this?

Edited by CarlML

Share this post


Link to post
Share on other sites

In D3D11 you can't have the same resource bound as both an input and an output. This means that you can't have a texture that's simultaneously bound as both a shader resource view, and as a render target view. When you bind render targets, the runtime will detect this case and force the shader resources to NULL if the shader resource view points to the same texture as a currently-bound render target view. Note that it will only do this for SRV's that are also bound as an RTV (or as a UAV): it won't unbind any SRV's that are still legally bound.

 

I would *highly* suggest enabling the D3D debug layer for your development builds. All you need to do is pass D3D11_CREATE_DEVICE_DEBUG when you call D3D11CreateDevice, and the debug layer will output messages to your debugger output window whenever you use the API incorrectly.

I did what you suggested and I'm getting tons of this warning:

 

D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets: Resource being set to OM RenderTarget slot 1 is still bound on input! [ STATE_SETTING WARNING #9: DEVICE_OMSETRENDERTARGETS_HAZARD]
D3D11 WARNING: ID3D11DeviceContext::OMSetRenderTargets[AndUnorderedAccessViews]: Forcing PS shader resource slot 1 to NULL. [ STATE_SETTING WARNING #7: DEVICE_PSSETSHADERRESOURCES_HAZARD]
So should I "unset" render targets and all their used resources before setting a new one? Having textures as render tagets and shader resources at the same time is not what I'm wishing for. Interesting that you say it does not always unbind them, I'll have to test some more because it seemed that rendering the shadow map to a completely different render target unbinded some of the G-buffer used as resources in other render targets.
Edited by CarlML

Share this post


Link to post
Share on other sites

So should I "unset" render targets and all their used resources before setting a new one? Having textures as render tagets and shader resources at the same time is not what I'm wishing for. Interesting that you say it does not always unbind them, I'll have to test some more because it seemed that rendering the shadow map to a completely different render target unbinded some of the G-buffer used as resources in other render targets.


yes, when switching a resource between input and output of the pipeline, you have to manually unset the other state.
This will do insert some barriers to guarantee correct results. for example, it will make sure that the data is written before it is read again (in case of a RT->SRV transition).
Note that this guarantee is part of the d3d11 driver, in newer APIs you have to do this explicitly.

Share this post


Link to post
Share on other sites

In my engine I actually tell D3D11 to unbind all currently bound SRV's (replace them with null pointers) before I bind any RTV's for the specific purpose of fixing these warnings :D

 

Also, I keep a cache of which SRV's I currently have bound, so I can avoid redundantly binding them again... but D3D's hidden behaviour of automatically unbinding things (and issuing a warning about it) would mess up my cache, as my cache would tell me that an SRV is still bound, while D3D has actually unbound it behind the scenes!

So if you want to do any kind of caching of resource bindings, you have to make sure that you've fixed all of those warnings.

 

Originally I only unbound SRV's that clashed with the new RTV's, but I found it simpler to simply nuke every SRV binding :lol:

Edited by Hodgman

Share this post


Link to post
Share on other sites

Thanks, I've got a better undestanding of how it works now. I've gotten rid of all the warnings and realized that I only need to unbind the resources affected by render target changes, so much of the G-buffer can stay bound throughout the frame, which gets rid of the wasteful calls I was doing. Things are moving along, thanks.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this