2D массив в постоянном буфере - PullRequest
0 голосов
/ 01 июля 2019

Я пытаюсь передать двумерный массив с плавающей точкой в ​​постоянный буфер:

//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 [размер / 4] [размер]

в моем cbuffer и многих других комбинациях типов, но я никак не могу получить доступ к своему массиву путем индексации. Как правильно это сделать?

Спасибо.

1 Ответ

0 голосов
/ 03 июля 2019

У меня была эта проблема, и она сводится в основном к выравниванию буфера. Ваше определение cbuffer в HLSL, скорее всего, будет дополнять то, что вы определили в своей структуре.

Выравнивание, вероятно, вдоль выравнивания 16 байтов (4 числа с плавающей запятой). В моем коде я писал 4 плавающих в буфер. Как это показано ниже, поскольку выравнивание массива в 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];  

Затем я ссылался на соответствующий элемент как Волна [0] .x, Волна [0] .y, Волна [0] .z, Волна [0] .w

Выравнивание памяти увеличило бы буфер в 4 раза, если бы я не упаковал его таким образом. Это связано с тем, что в коде HLSL определение буфера выравнивает каждый элемент массива по 16-байтовым границам (4 x с плавающей запятой). Поэтому вместо этого я сплел свои 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 байтов после каждого элемента в массив. Я уверен, что кто-то ответит правильной директивой компилятора, чтобы избавиться от этой причуды, я только что решил это некоторое время назад, и ваша проблема выглядит так же, как у меня.

...