在 HLSL 中注册范围?

Register Ranges in HLSL?

我目前正在重构大量旧代码,并最终进入 HLSL 部分,由于缺乏实践,我的知识很少。我在网上遇到 some documentation 指定哪些寄存器用于哪些目的:

  • t – for shader resource views (SRV)
  • s – for samplers
  • u – for unordered access views (UAV)
  • b – for constant buffer views (CBV)

这部分不言自明。如果我想创建一个常量缓冲区,我可以声明为:

cbuffer LightBuffer: register(b0) { };
cbuffer CameraBuffer: register(b1) { };
cbuffer MaterialBuffer: register(b2) { };
cbuffer ViewBuffer: register(b3) { };

然而,来自MIPS Assembly的世界,我不禁想知道这些是否存在有限和受限的范围。例如,临时寄存器被限制在 MIPS Assembly 中的 t0 - t7 范围内。在 HLSL 的情况下,我找不到任何关于该主题的文档,因为所有内容似乎都指向汇编语言和微处理器(例如 8051,如果您想阅读一个随机主题) .


HLSL 中的四种寄存器类型是否有固定范围,或者我只是按顺序按需要继续进行,让底层程序集处理杂乱的细节?


备注

我已经部分回答了这个问题,因为我目前无法找到 u 的范围;但是,如果有人有比我通过测试给出的答案更好、更详细的答案,请随时 post 它,我会将其标记为正确答案。我会将这个问题保留到 2018 年 12 月 1 日,以便其他人有机会为未来的读者提供更好的答案。

由于此类问题通常需要等待很长时间,因此我通过尝试在寄存器 b51 中创建 cbuffer 来测试 b 寄存器。正如我所料,这失败了,幸运的是 SharpDX 吐出一个异常,表明它有最大值 14。因此,为了未来的读者,我正在测试所有四种寄存器类型,并 post返回我发现成功的范围。

  • b 的范围是 b0 - b13.
  • s 的范围是 s0 - s15.
  • t 的范围是 t0 - t127.
  • u 的范围是 </code>.</li> </ul> <p>目前,我无法找到 <code>u 寄存器的范围,因为我的代码中没有它的示例,而且我实际上从未使用过它。如果有人提出确实有示例用法,请随时对其进行测试并为未来的读者更新此 post。


    在我的问题中链接的文档中,我确实发现了与我上面的发现相矛盾的地方;他们有一个使用 t 寄存器的示例,该寄存器高于此答案中提到的范围:

    Texture2D                     a[10000] : register(t0);
    Texture2D                     b[10000] : register(t10000);
    ConstantBuffer<myConstants>   c[10000] : register(b0);
    

    备注

    我想指出,我使用的是 HLSL 编译器的 SharpDX 版本,因此我不确定这些范围是否因编译器而异;我非常怀疑他们是否这样做,但在你尝试超越他们之前你永远不会太确定。 GLSL 由于与 HLSL 相似,可能相同,但也可能非常不同。

Resource Limit msdn 页面中指定了资源槽数(对于 d3d11,实际上是 d3d12 的案例扩展)。

您感兴趣的是:

  • D3D11_COMMONSHADER_INPUT_RESOURCE_REGISTER_COUNT(即 t)=128
  • D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT(即s)=16
  • D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT(即 b)= 15 但保留一个以最终存储来自着色器的一些常量数据(例如,如果你有一个静态常量大数组)

u 的情况不同,因为它取决于功能级别(tbh 是 vendor/os 版本混乱):

  • D3D11_FEATURE_LEVEL_11_1 或更大,这是 64 个插槽
  • D3D11_FEATURE_LEVEL_11 : 它永远是 8(但有些 cards/driver 最终支持 64,你至少需要 windows 8(它也可能在 windows 7 也有一些平台更新。我不记得有一种方法可以测试是否支持 64(例如,许多 nvidia 在他们的 700 范围内)。
  • D3D11_FEATURE_LEVEL_10_1:0 或 1,有一种方法可以检查是否支持计算

您需要执行 feature check:

D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS checkData;

d3dDevice->CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, &checkData);

BOOL computeSupport = checkData.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x 

请注意,对于某些 OS/Driver 版本,我让此标志返回 TRUE 但不受支持(英特尔在 win7/8 上这样做),因此在这种情况下,唯一有效的解决方案是尝试创建一个小的原始/字节地址缓冲区或结构化缓冲区并检查 HRESULT

作为旁注功能,功能级别 10 或以下适用于当今相当旧的配置,因此除了极少数情况外,您可以安全地忽略它(我只是将其保留以供参考)。