常量缓冲区中的2D数组

时间:2019-06-30 23:28:47

标签: c++ directx-11 hlsl

我正在尝试将2D浮点数组传递给常量缓冲区:

//In the shader:
    cbuffer myBuffer
    {
        other buffer elements
        .
        .
        float myArray[16][16];
    };

//In the CPU:
    struct  myBuffer_struct
    {
        other buffer elements
        .
        .
        float myArray[16][16];
    };

但是我在处理填充方面有很多问题。我尝试使用

  

float4 [size / 4] [size]

在我的cbuffer和许多其他类型组合中,但是我无法以任何方式通过索引访问我的数组。正确的方法是什么?

谢谢。

1 个答案:

答案 0 :(得分:0)

我遇到了这个问题,基本上可以归结为缓冲区的对齐。您的HLSL cbuffer定义绝对会与您在结构中定义的填充不同。

对齐方式可能沿16字节(4个浮点数)对齐。在我的代码中,我正在写4个float到一个缓冲区中。像下面这样,因为cbuffer中的数组对齐方式不同。

         for (int i = 0; i < 8; i++)
        {
            stream.Write<float>(m_waveLengths[i] ); 
            stream.Write<float>(m_waveSpeeds[i] );
            stream.Write<float>(m_amplitudes[i] ); 
            stream.Write<float>(m_steepness[i]); 
        }

要阅读此内容,我使用了float4数组定义。

// hlsl definition
float4 Wave[8];  

然后我将相关项目引用为Wave [0] .x,Wave [0] .y,Wave [0] .z,Wave [0] .w

如果不这样打包,内存对齐将使缓冲区大4倍。这是因为在HLSL代码中,缓冲区定义似乎沿16个字节边界(4个浮点数)对齐了数组的每个元素。因此,我将4个数组交织为1个数组,并使用float4的属性对其进行引用。

因为float waveLengths [8]的对齐意味着我必须像这样将其写入缓冲区:

   for (int i = 0; i < 8; i++)
        {
            stream.Write<float>(m_waveLengths[i] ); 
            stream.Write<float>(0.0f);
            stream.Write<float>(0.0f); 
            stream.Write<float>(0.0f); 
        }

由于某种原因(并且我可能未设置某个HLSL编译器指令),在Cbuffer中使用数组会有一些怪异之处,它们会将每个元素填充到16字节边界。

因此,对于您的float myArray [16] [16],我假设您看一下对齐方式,您可能必须以类似的方式为此写缓冲区,在缓冲区中的每个元素后填充12个字节。数组。我确信有人会用正确的编译器指令做出响应,以摆脱这种怪癖,我刚刚解决了这一问题,而您的问题与我的问题相似。