Bind nullptr at the end of rendering of something, important ?

Started by
3 comments, last by Hodgman 7 years ago

Hi,
I only bind nullptr for shader resource which needs to not be bound same time but for all others I let them bound.
Is it better to always unbind shader resources at the end of the rendering of something ?
I read long time ago one comment from intel sample : "make the driver happy".
Thanks

Advertisement

I wouldn't think so. Honestly, I thought it was the other way around, keep the pipeline the same for as many draws as possible. Combining like objects in terms of shaders, resources, buffers, what have ya. I could be misunderstanding though.

Marcus

We minimize the number of API calls and only set whatever we need for the draw call as we go.

Generally speaking unbinding is not only unnecessary, but will actually make your code fragile and error-prone.

The best practice is to bind everything you need before each draw. This should include all state, shaders, buffers, textures, etc. Add a state-filtering layer to ensure that you don't incur unnecessary overhead from redundant changes, but do nothing after drawing.

This mirrors the PSO model in more modern APIs, and helps to ensure that no draw call is dependent on or affected by inherited state from a prior call, so it should be obvious that it's all good stuff.

With this kind of model unbinding is not needed, and in fact will break your state filtering.

There are of course exceptions; for example, in D3D11 binding an object will cause the runtime to hold an additional reference to it, so to complete destruction of that object you must first unbind it (or use ClearState) otherwise you'll leak the reference. Similarly, render targets must be unbound before calling ResizeBuffers, and a texture with both a shader resource view and a render target view must be unbound from one before binding to the other.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

L
You can't have a resource bound for reading and writing at the same time. This often accidentally happens with post-processing, where you've left something bound as an SRV, and then also bind it as an RTV. Even if that particular SRV slot isn't used by your shaders, this is an error that you have to prevent. So read+write resources need some special unbinding code.

If a resource is bound to any binding slot, its reference counter will be incremented for the duration of the binding.
If one object in your game binds a texture to SRV slot #42, but no other object ever rebinds something else over the top of it, then this is essentially a memory leak. Even if you release all of your references to the resource, the binding will prevent it from being deleted.
To avoid this, I clear the D3D state and all bindings at the beginning of every frame.

This topic is closed to new replies.

Advertisement