Jump to content
  • Advertisement
Sign in to follow this  
EbonySeraphim

DX11 [DX11] Handling Multiple ResourceViews with Multislotted Resources

This topic is 2760 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

I'm trying to write a generic wrapper for DX11 shaders to abstract the code that will allow setting resources, samplers, constant buffers, etc. I was wondering how multiple resource views get handled when the resources themselves are multi-slotted and you make a single call to *SSetShaderResources(). For example, what happens when there's a call to *SSetShaderResources() for slot 0 and the underlying resource is an array of 4 2D textures? I presume this would fill up slots 0-3. The call for that would look like this:
p_Device->*SSetShaderResources(0, 1, &pMultiSlotRV);  //underlying resource is Texture2D[4] so it uses 4 slots

So then my question is, what if you had a resource view immediately after that resource? Obviously on the graphics hardware, you would want that placed in slot 4. With a separate call to *SSetShaderResources() the code would look like:
p_Device->*SSetShaderResources(4, 1, &NextRV);  //manually inserted after the previous resource (but requires knowledge of it's placement)

Successively called:

p_Device->*SSetShaderResources(0, 1, &pMultiSlotRV);
p_Device->*SSetShaderResources(4, 1, &NextRV);

The question is what happens if you want to set both resources in the same call to *SSetShaderResources(), or is that is even possible? Basically what would happen with this snippet of code:

ID3D11ShaderResourceView * twoRV[2];
twoRV[0] = pMultiSlotRV; //uses slots 0-3
twoRV[1] = NextRV; //uses slot 4
p_Device->*SSetShaderResources(0, 2, &twoRV);

It seems to me that the above code would get unrolled into two calls that look like this:

p_Device->*SSetShaderResources(0, 1, &pMultiSlotRV);
p_Device->*SSetShaderResources(1, 1, &NextRV);

So the that would cause the first resource to fill slots 0-3, but then the next resource view would overwrite whatever is in slot 1 which is supposed to be a part of the first resource that is multi-slotted. Can someone explain what the behavior is in the senario of making 1 call with both resource reviews in an an array? It would spare me a lot of time staring at a screen with garbage (given I'm still pretty newb). Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
If you're using a texture array, then it takes just one slot and you access it in the shader as a Texture2DArray instead of a Texture2D. So when you sample it, you specify which texture in the array to use, in addition to the texture coordinate.

Share this post


Link to post
Share on other sites
My point confusion lies in the fact that I'm writing a lot of this code based on the reference documentation and am using ShaderReflection. The D3D11_SHADER_INPUT_BIND_DESC structure has BindPoint and BindCount members. Can you explain how those correlate to number of resource views and start slot that should be used to set the associated parameters?

I'm tinkering around with reflection, examining the output of it based on changing the structure of shaders, and it seems that explicit arrays are flattened into their separate components as used and occupy separate bind slots. I tested a Texture2DArray and that only occupies one too. So really, what is the difference between Texture2DArray and Texture2D[n]? I may be asking these questions far too early.

Share this post


Link to post
Share on other sites
The difference between Texture2DArray and Texture2D[n] is the the Texture2DArray is a single resource with multiple subresources referred to as texture slices. A Texture2D[n] is just an array of individual, independent resources.

The other thing to keep in mind is that a shader resource view is used to bind a resource to the pipeline. You can create a separate shader resource view over each subresource of a Texture2D or Texture2DArray, where a subresource can be from mip maps or texture slices (see the docs for details about what can be selected with a SRV). Therefore, if you declare in HLSL Texture2D[n], then you can create one shader resource view for each of the mip maps of a single Texture2D and bind them to 'n' SRV slots. In HLSL it will appear as an array of unrelated resources, but in C++ it is actually all the same resource.

You just need to get used to the difference between a shader resource view and the resources that stand behind them.

Share this post


Link to post
Share on other sites
I think I have a better understanding now. If I go back to my original issue, there really isn't one at all. What I called a multi-slot resource view, cannot really exist. If I create a 2D texture array programmatically, with only a single resource view, in HLSL it will still only take up 1 slot no matter how big the array is. Ideally that slot should populate Texure2DArray variable in HLSL correct? Also, if I force-fit a Texture2DArray into a Texture2D or Texture1D in HLSL, it would just be interpreted however it is being used which would likely be broken?

So every variable type declared in HLSL takes up only 1 resource-view/slot unless declared with array syntax. What is populated in that slot (a resource view) is just memory that will be interpreted when the HLSL uses variable.

Share this post


Link to post
Share on other sites
I'm not sure if the runtime will let you do that or not. At the very least, I would expect a warning when you actually execute the draw call that would use the texture.

When you create an SRV you specify the view dimension, which has distinct entries for Texture2D and Texture2DArray. I would suggest to try doing the cross setting and see what comes out of the debug output. This is often the only way to know for sure about edge cases like this, since they aren't directly specified in the documentation.

Share this post


Link to post
Share on other sites
Yeah I know for Texture2DMS you will get a warning in the debug spew that you have an incompatible view dimension, but I'm not sure whether it will do the same for Texture2DArray. I suspect it would have the same behavior.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!