OpenGL Compute Shader generating triangle indices: How to get correct element count for glDrawElementsIndirect? I have a sequence of compute shaders that generates an indexed mesh.The last one of those writes the generated indices like this:

void addTriangle (uint i0, uint i1, uint i2) {
    uint ic = atomicCounterIncrement(indirectIndexCount);
    meshIndices[ic*3+0] = i0;
    meshIndices[ic*3+1] = i1;
    meshIndices[ic*3+2] = i2;
}


After the mesh has been generated, it is drawn with glDrawElementsIndirect. The indirectIndexCount in the code above is an atomic_uint counter at position 0 inside the GL_DRAW_INDIRECT_BUFFER (see the struct called DrawElementsIndirectCommand). This counter is now obviously too small by a factor of three, since it was incremented only once for each triangle. Currently, I multiply it by 3 afterwards just before issuing the draw call.

(At the moment this is done by mapping the buffer and multiplying on the CPU, which is of course nonsense, but shows that the whole thing basically works. Everything is drawn correctly. I could do it with an invocation of a single 1x1x1x1x1x1 compute shader, but that seems only slightly less silly.)

How do I get rid of this extra multiplication step?

Since this seems to be an obvious problem whenever meshes with variable index count are generated, I guess there must be some easy solution that I'm overlooking?
If you have access to glsl 4.3+ (or glsl ES 3.1) you can use atomicAdd 

The next option is to use a barrier() after all vertices are generated in the compute and then multiplying the value in the counter:

main(){

    // generate vertices

    barrier();
    if(gl_localInvocationID == vec3(0)){
        indirectCount = atomicCounter(indirectIndexCount)*3;
    }
}


This emulates running another 1x1x1 compute shader to multiply the index.

Otherwise you can use a second atomic to hold the vertexcount:

void addTriangle (uint i0, uint i1, uint i2) {
    uint ic = atomicCounterIncrement(indirectIndex);
    meshIndices[ic*3+0] = i0;
    meshIndices[ic*3+1] = i1;
    meshIndices[ic*3+2] = i2;
    atomicCounterIncrement(indirectIndexCount);
    atomicCounterIncrement(indirectIndexCount);
    atomicCounterIncrement(indirectIndexCount);
}


Both indirectIndex and indirectIndexCount are initialized to 0 and indirectIndexCount is what is passed through to  glDrawElementsIndirect.