Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DirectX Shader Resource View in Shaders

I'm a bit confused right now and just want to ask you all to help me get a few ideas clarfied.

In a HLSL shader (compute shader for example) I can declare a StructuredBuffer sb, right? Do I HAVE to bind it to a register, such as : register(t0)?

From the application side, I can call CSSetShaderResources(...). The first argument (the StartSlot), does it have anything to do with the little number behind the "t" in the register declaration?

If I set the StartSlot as 0 (for example), and I set the second argument as 2. Am I telling the API that I'll binding two Shader Resource Views, one in register(t0) and another in register(t1)?

If I declare Texture2D tex[10] : register(t0) I can set it by calling CSSetShaderResources(0, 10, ...). Does this mean that registers(t0~t9) are all used up?

Sorry for such a "rapid fire" of questions, but I'm just really confused and some of my tests seem to give confliting results...

Any help would be appreciated.

like image 423
l3utterfly Avatar asked Sep 29 '12 09:09

l3utterfly


People also ask

What is a shader resource view?

Shader resource views typically wrap textures in a format that the shaders can access them. An unordered access view provides similar functionality, but enables the reading and writing to the texture (or other resource) in any order. Wrapping a single texture is probably the simplest form of shader resource view.

Does DirectX use shaders?

DirectX supports shaders and its implementation since version 8.0. The first support started with Vertex and Pixel Shaders written in Assembler language.

What are DirectX shaders?

DirectX Shader Cache are files created by the graphics system which can speed up application load time and improve performance. If deleted, they get regenerated automatically when needed.

What is Unordered access view?

An unordered access view (UAV) is a view of an unordered access resource (which can include buffers, textures, and texture arrays, though without multi-sampling). A UAV allows temporally unordered read/write access from multiple threads.


2 Answers

So let's reply in order:

Yes you can of course declare a StructuredBuffer in a compute shader (actually you can declare it for any type of shader).

If you don't use effect framework (techniques), you need to declare a register, so the shader will know where to read from your data (using effect framework it just does it under the hood, but you still can explicitely declare).

CSSetShaderResources tells to bind N resources from a start slot, so your description of using 0,2 is correct.

For array of textures, I had to run PIX to check it out, but it's indeed the way you said.

Texture2D tex[10] : register(t0); 

Will mean that each texture index will be allocated a slot starting from the register you specified, so you need to call CSSetShaderResources(0,10,srvarray) to set them.

like image 186
mrvux Avatar answered Sep 21 '22 20:09

mrvux


Very cool explanation! I also got confused, and after your questions and explanations it's clear for me!

But I found a good example for this post, which I want to share. It seems it starts the counter of the slot for every SetShaderResources Type. All shaders (VS, HS, DS, PS) seems to have theirs own counter. Here the code from a NVidia example:

The Shaderclass code:

pd3dDeviceContext->HSSetShaderResources( 0, 2, Resources ); 
pd3dDeviceContext->HSSetShaderResources( 8, 1, &m_pRegularWatertightTexSRV );
pd3dDeviceContext->HSSetShaderResources( 9, 1, &m_pQuadWatertightTexSRV );
pd3dDeviceContext->HSSetShaderResources( 2, 1, &pHeightMapTextureSRV );
pd3dDeviceContext->DSSetShaderResources( 2, 1, &pHeightMapTextureSRV );
pd3dDeviceContext->PSSetShaderResources( 2, 1, &pHeightMapTextureSRV );
pd3dDeviceContext->PSSetShaderResources( 10, 1, &pNormalMapTextureSRV );
pd3dDeviceContext->PSSetShaderResources( 3, 1, &pTexRenderRV11 );

The first is holding two resources, so the next slot (line 4) has to add 2 for the starting slot (0+2=2). Every SetShaderResources has to start with 0, but you can do that on different places in your code, therefore there is no 0 slot for DS and PS here. Some times if you remove a line it still works but the data is postponed. Now you see the first four in HLSL at line t0, t1, t8, and t9 the other register were bound somewhere else.

The HLSL code:

Texture2D<float> GregoryStencil               : register( t0 ); 
Texture2D<uint>  Index                        : register( t1 );    
Texture2D<float>  g_txHeight                  : register( t2 );       
Texture2D<float> g_depth                      : register( t3 ); 
Texture2D g_FloorTexture                      : register( t4 );  
Texture2D<float3>  regularPatchControlPoints  : register( t5 ); 
Texture2D<float3>  gregoryPatchControlPoints  : register( t6 ); 
Texture2D<float4>  g_floorHeight              : register( t7 );   
Texture2D<float2>  RegularWatertightUVs       : register( t8 );  
Texture2D<float2>  QuadWatertightUVs          : register( t9 );  
Texture2D<float3>  g_txNormal                 : register( t10 );
like image 42
Jinxi Avatar answered Sep 18 '22 20:09

Jinxi