OpenGL compute shader buffer allocation fails

2019-07-10 02:41发布

问题:

I am trying to use a buffer in a compute shader like this:

layout (binding = 1, std430) writeonly buffer bl1
{
    uint data[gl_WorkGroupSize.x * gl_NumWorkGroups.x * gl_NumWorkGroups.y];
};

but I get the following error (because of using gl_NumWorkGroups for the size):

Array size must be a constant integer expression

How can I work around this?

回答1:

Stop putting in a length at all:

layout (binding = 1, std430) writeonly buffer bl1
{
    uint data[];
};

This is a feature unique to SSBOs. And you can only have one unsized array in an SSBO, and it must be the last member in the interface block. The size of data will be computed based on the size of the buffer object range you bind to that binding point. So if you bind 32KB of buffer space, you will get 8K of items (the size of a uint is 4 bytes).

At runtime, your shader can use gl_WorkGroupSize.x * gl_NumWorkGroups.x * gl_NumWorkGroups.y to compute the length of data. Alternatively, just use data.length() to get the length of the buffer that the user gave you. Alternatively... you don't need to explicitly know the length, depending on how you use it.

As long as your OpenGL buffer binding code uses a buffer with enough memory for your dispatch count and work group size, you're fine.