7

我现在有点困惑,只是想请大家帮助我澄清一些想法。

在 HLSL 着色器(例如计算着色器)中,我可以声明一个 StructuredBuffer sb,对吗?我是否必须将其绑定到寄存器,例如:register(t0)?

从应用程序端,我可以调用 CSSetShaderResources(...)。第一个参数(StartSlot),它与寄存器声明中“t”后面的小数字有什么关系?

如果我将 StartSlot 设置为 0(例如),并将第二个参数设置为 2。我是否告诉 API 我将绑定两个着色器资源视图,一个在 register(t0) 中,另一个在 register(t1) 中?

如果我声明 Texture2D tex[10] : register(t0) 我可以通过调用 CSSetShaderResources(0, 10, ...) 来设置它。这是否意味着寄存器(t0~t9)都用完了?

抱歉,问题如此“迅速”,但我真的很困惑,我的一些测试似乎给出了令人困惑的结果......

任何帮助,将不胜感激。

4

2 回答 2

4

所以我们按顺序回复:

是的,您当然可以在计算着色器中声明一个 StructuredBuffer(实际上您可以为任何类型的着色器声明它)。

如果您不使用效果框架(技术),则需要声明一个寄存器,因此着色器将知道从哪里读取您的数据(使用效果框架它只是在后台执行,但您仍然可以明确声明)。

CSSetShaderResources 告诉从起始槽绑定 N 个资源,因此您对使用 0,2 的描述是正确的。

对于纹理数组,我不得不运行 PIX 来检查它,但这确实是你所说的方式。

Texture2D tex[10] : register(t0); 

这意味着每个纹理索引将从您指定的寄存器开始分配一个插槽,因此您需要调用 CSSetShaderResources(0,10,srvarray) 来设置它们。

于 2012-09-29T13:42:08.403 回答
2

很酷的解释!我也很困惑,在你的问题和解释之后,我很清楚!

但我为这篇文章找到了一个很好的例子,我想分享一下。似乎它为每个 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 行)必须为起始插槽(0+2=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 );
于 2013-10-23T10:39:48.270 回答