首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DirectCompute着色器(HLSL)有奇怪的阵列大小。

DirectCompute着色器(HLSL)有奇怪的阵列大小。
EN

Stack Overflow用户
提问于 2019-12-11 15:37:23
回答 1查看 559关注 0票数 0

顺便说一句,我还在苦苦挣扎,电脑着色器存储了一个uint数组。我有以下着色器代码(一个简单的极简示例来再现问题):

代码语言:javascript
运行
复制
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 UIntArray10;“的大小为148个字节。这很奇怪,因为uint是4个字节。因此,我预计数组大小为40字节。

下面是编译器的输出:

代码语言:javascript
运行
复制
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:\Development\Projects\Test Projects\DirectCompute\TestShader1.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

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

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-11 22:18:16

引用Microsoft的话

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

因此,uint UIntArray[10];实际上是作为一个uint4 UIntArray[10];存储的,除了最后三个填充点不包括在大小计算中(尽管它们仍然计算在偏移量计算中)。

如果需要更紧密的打包,可以将数组声明为uint4 UInt4Array[4];,然后将其转换为:static uint UInt1Array[16] = (uint[16])TCstParams.UInt4Array; (没有检查该代码是否正确,但应该是类似的)。转换本身不应造成任何开销-但是,UInt1Array中的累积元素将引入额外的指令来计算实际偏移量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59289246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档