0
votes

Im trying to pass a 2D float array to a constant buffer:

//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];
    };

But im having a lot of problems dealing with the padding. I tried using

float4[size/4][size]

in my cbuffer and a lot of other type combinations but I cant access to my array by indexation in any way. What is the proper way to do this?

Thank you.

1
Get rid of the padding by using the appropriate compiler options. If your struct needs to be byte-packed, then specify it by using a #pragma or whatever means your compiler uses.PaulMcKenzie
I'm confused by why would there be padding in a struct that contains a single member, whose alignment requirement is less than its own size. There cannot be padding between elements of an array.eerorika
I have more elements in my struct, not only the 2D arrayKeles
For cbuffer padding the details (sizes and orders) of all fields are important as they depend on each other. Can you post your whole definition of both declarations?Gnietschow

1 Answers

0
votes

I've had this issue and it comes down to basically the alignment of the buffer. Your HLSL cbuffer definition most definitely will be padding differently to what you have defined in your struct.

The alignment probably along 16 byte (4 floats) alignment. In my code, I was writing 4 floats out into a buffer. Like this below, as the array alignment was different in the 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]); 
        }

To read this, I used a float4 array definition.

// hlsl definition
float4 Wave[8];  

I then referenced the relevant item as Wave[0].x, Wave[0].y, Wave[0].z, Wave[0].w

The memory alignment would make the buffer 4 times bigger if I didn't pack it like this. This is because in the HLSL code, the buffer definition seems to of aligned each element of the array along 16 byte boundries (4 x floats). So instead, I interweaved my 4 arrays into 1 array and used the properties of float4 to reference it.

because the alignment of float waveLengths[8] would of meant that I would have to write it into the buffer like this:

   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); 
        }

For some reason (and I am probably not setting a certain HLSL compiler directive), using arrays in the Cbuffer had some quirks where it would pad each element to a 16 byte boundary.

So, for your float myArray[16][16], I would assume that you look at the alignment, you may have to write the buffer for this out in a similar manner, padding out 12 bytes after each element in the array. I'm sure someone will respond with correct compiler directive to get rid of this quirk, I just solved this a while ago and your problem looks similar to what I had.