DirectCompute shader (HLSL) 具有奇怪的数组大小



我正在努力解决计算着色器存储uint数组的方式。 我有以下着色器代码(一个简单的极简主义示例来重现问题(:

cbuffer TCstParams : register(b0)
{
int    IntValue1;
uint   UIntArray[10];    // <== PROBLEM IS HERE
int    IntValue2;
}
RWTexture2D<float4>                Output         : register(u0);
[numthreads(1, 1, 1)]
void CSMain()
{
if (IntValue1 == 0)
Output[uint2(0, 0)] = float4(1, 1, 1, 1);
}

编译完成后,我检查编译器的输出以了解常量缓冲区项的函数和大小。令人惊讶的是,"uint UIntArray[10];"项的大小为148字节。考虑到 uint 是 4 个字节,这很奇怪。所以我希望数组大小为 40 字节。

下面是编译器输出:

Microsoft (R) Direct3D Shader Compiler 6.3.9600.16384
Copyright (C) 2013 Microsoft. All rights reserved.
//
// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
//
//
// Buffer Definitions: 
//
// cbuffer TCstParams
// {
//
//   int IntValue1;                     // Offset:    0 Size:     4
//   uint UIntArray[10];                // Offset:   16 Size:   148 [unused]    // <== PROBLEM IS HERE
//   int IntValue2;                     // Offset:  164 Size:     4 [unused]
//
// }
//
//
// Resource Bindings:
//
// Name                                 Type  Format         Dim Slot Elements
// ------------------------------ ---------- ------- ----------- ---- --------
// Output                                UAV  float4          2d    0        1
// TCstParams                        cbuffer      NA          NA    0        1
//
//
//
// Input signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name                 Index   Mask Register SysValue  Format   Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed | skipOptimization
dcl_constantbuffer cb0[1], immediateIndexed
dcl_uav_typed_texture2d (float,float,float,float) u0
dcl_temps 2
dcl_thread_group 1, 1, 1
#line 13 "E:DevelopmentProjectsTest ProjectsDirectComputeTestShader1.hlsl"
if_z cb0[0].x
mov r0.xyzw, l(0,0,0,0)
itof r1.xyzw, l(1, 1, 1, 1)
store_uav_typed u0.xyzw, r0.xyzw, r1.xyzw
endif 
ret 
// Approximately 6 instruction slots used

我检查了各种数组大小,结果非常奇怪:当元素数量发生变化时,每个元素的大小会有所不同!

我做错了什么或错过了什么? 谢谢。

引用Microsoft文档:

默认情况下,数组不打包在 HLSL 中。为了避免强制着色器承担偏移计算的 ALU 开销,数组中的每个元素都存储在一个四分量向量中。

所以uint UIntArray[10];实际上存储为uint4 UIntArray[10];,除了最后三个填充uint不包括在大小计算中(即使它们仍然计入偏移计算(。

如果你想要更紧密的包装,你可以将数组声明为uint4 UInt4Array[4];然后强制转换它:static uint UInt1Array[16] = (uint[16])TCstParams.UInt4Array;(尚未检查该代码是否正确,但它应该是类似的东西(。强制转换本身不应引起任何开销 - 但是,UInt1Array中的 accass 元素将引入额外的指令来计算实际偏移量。

相关内容

  • 没有找到相关文章

最新更新