C++ 着色器中的DirectX着色器资源视图
我现在有点困惑,只想请你们帮我澄清一些想法 在HLSL着色器(例如计算着色器)中,我可以声明StructuredBuffer sb,对吗?我是否必须将其绑定到寄存器,例如:register(t0) 从应用程序方面,我可以调用CSSetShaderResources(…)。第一个参数(StartSlot)是否与寄存器声明中“t”后面的小数字有关 如果我将StartSlot设置为0(例如),并且将第二个参数设置为2。我是否告诉API我将绑定两个着色器资源视图,一个在寄存器(t0)中,另一个在寄存器(t1)中 如果我声明texture2dtex[10]:register(t0),我可以通过调用CSSetShaderResources(0,10,…)来设置它。这是否意味着寄存器(t0~t9)都用完了 很抱歉问了这么多问题,但我真的很困惑,我的一些测试似乎给出了混淆的结果C++ 着色器中的DirectX着色器资源视图,c++,directx,shader,hlsl,compute-shader,C++,Directx,Shader,Hlsl,Compute Shader,我现在有点困惑,只想请你们帮我澄清一些想法 在HLSL着色器(例如计算着色器)中,我可以声明StructuredBuffer sb,对吗?我是否必须将其绑定到寄存器,例如:register(t0) 从应用程序方面,我可以调用CSSetShaderResources(…)。第一个参数(StartSlot)是否与寄存器声明中“t”后面的小数字有关 如果我将StartSlot设置为0(例如),并且将第二个参数设置为2。我是否告诉API我将绑定两个着色器资源视图,一个在寄存器(t0)中,另一个在寄存器(
任何帮助都将不胜感激。因此,让我们按顺序回复: 是的,您当然可以在计算着色器中声明StructuredBuffer(实际上,您可以为任何类型的着色器声明它) 如果不使用“效果框架”(effect framework)(技术),则需要声明一个寄存器,以便着色器知道从何处读取数据(使用“效果框架”(effect framework),它只是在引擎盖下执行,但您仍然可以显式声明) CSSetShaderResources告诉您从一个开始槽绑定N个资源,因此您对使用0,2的描述是正确的 对于纹理数组,我必须运行PIX来检查它,但这确实是您所说的方式
Texture2D tex[10] : register(t0);
这意味着每个纹理索引将从您指定的寄存器开始分配一个插槽,因此您需要调用CSSetShaderResources(0,10,srvarray)来设置它们。非常酷的解释!我也感到困惑,在你的问题和解释之后,我明白了 但是我为这篇文章找到了一个很好的例子,我想与大家分享。似乎它会为每个SetShaderResources类型启动插槽的计数器。所有着色器(VS、HS、DS、PS)似乎都有自己的计数器。以下是NVidia示例中的代码: 着色器类代码:
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 );
第一个存储两个资源,因此下一个插槽(第4行)必须为起始插槽添加2(0+2=2)。每个SetShaderResources都必须以0开头,但您可以在代码中的不同位置执行此操作,因此这里没有用于DS和PS的0插槽。有时,如果删除一行,它仍然可以工作,但数据会延迟。
现在您可以看到HLSL中的前四个寄存器位于第t0、t1、t8和t9行,另一个寄存器绑定在其他地方
HLSL代码:
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 );
Texture2D GregoryStencil:寄存器(t0);
纹理2d索引:寄存器(t1);
纹理2d g_txHeight:寄存器(t2);
纹理2d g_深度:寄存器(t3);
纹理2D g_FloorTexture:寄存器(t4);
纹理2D常规补丁控制点:寄存器(t5);
纹理2D GregoryPatch控制点:寄存器(t6);
纹理2D g_地板光线:寄存器(t7);
纹理2D调节防水:寄存器(t8);
纹理2d:寄存器(t9);
纹理2d g_txNormal:寄存器(t10);
非常感谢。这就解决了很多问题。。。为了确保,对于texture2dtex[10]:register(t0),我不能使用register(t1)或register(t2)声明另一个变量。。。直到寄存器(t9)之后,因为它们都会用完,对吗?(我给了你一个+1,非常明确的答案,再次感谢。在我澄清最后一点后,我会将其标记为接受)这是正确的,如果你试图将多个变量绑定到同一寄存器,编译器会给你这个错误“重叠寄存器语义尚未实现”。