Reputation: 1068
Suppose I have an array variable in a shader, declared in a shader storage block:
layout(std430, binding = 2) buffer MyBuffer
{
float lotsOfFloats[];
};
and a struct:
struct myStruct
{
float f1;
vec3 vf1;
}struct1;
Is there a way to "quickly" initialize an object of this structure in a shader using the values in the array in a buffer storage block ( in the lotsOfFloats array in this example)? Say, in C++ one can copy memory from the array to the object:
memcpy(&struct1, &lotsOfFloats[0], sizeof(myStruct) );
Or one can byte copy array values to the object through assignment:
struct1 = *(myStruct*)&lotsOfFloats[0];
Is there a similar way in GLSL? E.g. will work the second way (byte copy assignment) in GLSL?
Upvotes: 2
Views: 2471
Reputation: 43369
Rather than treating your SSB as an unstructured array of floats, you can actually declare it as an unsized array of your structure:
struct myStruct
{ // Addresses Occupied
float f1; // 0N
vec3 vf1; // 1N,2N,3N
};
layout(std430, binding = 2) buffer MyBuffer
{
myStruct lotsOfStructs[];
};
GPUs do not like most 3-component data types and generally have to treat them like 4-component for proper alignment. Thus, vec3
has the same alignment rules as vec4
.
Right now, you have a vec3
beginning on the wrong boundary. vec3
and vec4
data types need to be aligned to a multiple of 4N (where N is the size of a float
).
vf1
and f1
:struct myStruct
{ // Addresses Occupied
vec3 vf1; // 0N,1N,2N
float f1; // 3N
};
(Single-precision) scalars can be aligned on any boundary since they have a size 1N, so you can put f1
right after vf1
with no problems.
You might find it useful to know that with std430
, there is one additional requirement that says the size of the struct must be a multiple of the largest base alignment. In this case the largest base alignment of any member in this struct is for vf1
(vec3
), which has a base alignment of 4N.
That means that if you did not have f1
at the end of the structure (its size would be 3N), GL would automatically add 1N worth of padding to the end of the structure and you would need to account for GL's behavior in your C code. Your structure is already 4N aligned, so you are good to go, but if you did not know this it could come a surprise later on.
You should read up on 7.6.2.2 Standard Uniform Block Layout
, alignment is very important when dealing with Shader Storage Buffers and Uniform Buffers.
Upvotes: 7