0
votes

Say I have some struct MyUniform:

struct MyUniform {
   /*...*/
};

and I have an array of 10 of them so on the host in C like:

MyUniform my_uniform_data[10] = /*...*/;

and I want to access all ten (as an array) from a shader.

In VkDescriptorSetLayoutBinding it has a field descriptorCount:

descriptorCount is the number of descriptors contained in the binding, accessed in a shader as an array.

So I assume at least one way to get this array to a shader is to set descriptorCount to 10, and then I would be able in GLSL to write:

layout(set = 2, binding = 4) uniform MyUniform {
    /*...*/
} my_uniform_data[10];

Now when writing the VkDescriptorSet for this I would have a single buffer with 10 * sizeof(MyUniform) bytes. So in a VkWriteDescriptorSet I would also set descriptorCount to 10, and then I would have to create an array of 10 VkDescriptorBufferInfo:

VkDescriptorBufferInfo bi[10];
for (int i = 0; i < 10; i++) {
    bi[i].buffer = my_buffer;
    bi[i].offset = i*sizeof(MyUniform);
    bi[i].range = sizeof(MyUniform);
}

This kind of arrangement clearly accomodates where each array element can come from a different buffer and offset.

Is there a way to arrange the descriptor layout and updating such that the entire array is written with a single descriptor?

Or is the only way to update a GLSL uniform array to use multiple descriptors in this fashion?

1
For your case only one VkWriteDescriptorSet is needed but I don't think that you can create one VkDescriptorBufferInfo for all your uniform buffers. Why do you want to do that? What is the disadvantage of using several VkDescriptorBufferInfo?Arthur Monteiro

1 Answers

2
votes

Descriptor arrays create arrays of descriptors(for example buffers); But what you need is array of structs in a buffer:

struct myData{
    /*...*/
};

layout(set = 2, binding = 4)uniform myUniform {
    myData data[];
};

And remember about alignment.