This question is a continuation of this subject : How to bind thousands of buffers properly
This problem is related to the particle simulation subject. Let say I need a global structure that includes :
- A 3D matrix (32*32*32) of uints (holding header id of a hashed linked list).
- A counter that tells me the amount of particles in my hashed linked list.
- A hashed linked list of particles.
The first idea was to use a 3D texture for the first item, an atomic counter buffer for the second, and a SSB for the third.
Each entry in the SSB is a particle plus a uint which value points to the location of the next particle in the same voxel.
Nothing magical here.
Now, in order to be space independent (not bound to a unique cubic space) I must be able to pass particles from a cube to others surrounding it. Since I'm in a 3D space, 27 cubes (front) as input variables for physical computation, but also 27 cubes (back) as output since I may write a particle from a cube (front) to an other (back) covering a different part of the space.
This leads me to a requirement in bindings of 54 textures, 54 SSB and 54 atomic counters. While the two firsts may not be a problem (my hardware limit is around 90 for both), the ACB binding limit is 8.
Assuming having a single ACB containing the particle count of each cube is not easy to maintain (I didn't give a long time to the thought, it may be the solution, but this is not the question here).
CONTEXT :
A SSB can contain anything. So a solution would be to concatenate the three structures (header matrix, counter and linked list) inside one SSB that will be my cube super structure.
I need before each pass to know how many particles are inside the SSB to do a proper glDispatchCompute() call.
QUESTION :
Would it be bad to bind the SSB just to read the uint that contains the amount of particles ?
If no, is one of the two methods to access the count better than the other ? Why ?
GLuint value;
//1st method
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer);
m_pFunctions->glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, OFFSET_TO_VALUE, sizeof(GLuint), &value);
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
//2nd method
m_pFunctions->glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, m_buffer, OFFSET_TO_VALUE, sizeof(GLuint));
m_pFunctions->glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(GLuint), &value);
m_pFunctions->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
If no, is there a good way or should I separate the counter from the SSB ?
coherent
and use an appropriate barrier. That said it really sounds like what you are actually trying to do could be done using DispatchIndirect. – Andon M. ColemanglMemoryBarrier (...)
command) and coherence are the tools necessary for that, you want the other invocations to wait their turn and you also want them to be aware of changes to the SSB's value by parallel invocations. – Andon M. Coleman