<p>If you have access to glsl 4.3+ (or glsl ES 3.1) you can use <a href="http://docs.gl/sl4/atomicAdd" rel="noreferrer">atomicAdd</a> </p>

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

<pre><code>main(){

    // generate vertices

    barrier();
    if(gl_localInvocationID == vec3(0)){
        indirectCount = atomicCounter(indirectIndexCount)*3;
    }
}
</code></pre>

<p>This emulates running another 1x1x1 compute shader to multiply the index.</p>

<p>Otherwise you can use a second atomic to hold the vertexcount:</p>

<pre><code>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);
}
</code></pre>

<p>Both <code>indirectIndex</code> and <code>indirectIndexCount</code> are initialized to 0 and <code>indirectIndexCount</code> is what is passed through to  <code>glDrawElementsIndirect</code>.</p>

CC BY-SA 3.0
2015-10-13T14:33:49.207Z
I like the second idea because it makes clear that I need two different things: A way to atomically add triangles and a way to get the final index count. Doesn't have to be the same mechanism. And yes, I'll try atomicAdd as well. As Nathan suggested in a comment above, it would be interesting to see if it really is slower. I'll report back with the findings.
cupe
CC BY-SA 3.0
2015-10-13T22:15:00.713Z
Can confirm that atomicAdd is indeed not slower for this use case on nvidia kepler ( ~1.5k indices: 0.1ms - probably needs larger size for meaningful benchmark). Binding the indirect command buffer as an SSBO and writing to the uint at position 0 works fine. Sometimes one should just try the easy solutions first...
cupe
CC BY-SA 3.0
2015-10-13T08:36:08.430Z
2015-10-13T14:44:20.010Z
2015-10-13T14:44:20.010Z
ratchet freak
<p>I have a sequence of compute shaders that generates an indexed mesh.The last one of those writes the generated indices like this:</p>

<pre><code>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;
}
</code></pre>

<p>After the mesh has been generated, it is drawn with <a href="http://docs.gl/gl4/glDrawElementsIndirect">glDrawElementsIndirect</a>. The <em>indirectIndexCount</em> in the code above is an <em>atomic_uint</em> counter at position 0 inside the <em>GL_DRAW_INDIRECT_BUFFER</em> (see the struct called <em>DrawElementsIndirectCommand</em>). 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.</p>

<p>(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.)</p>

<p>How do I get rid of this extra multiplication step?</p>

<p>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?</p>

CC BY-SA 3.0
2015-10-12T22:38:52.533Z
Can you atomic-add 3 to the counter instead of incrementing it?
Nathan Reed
CC BY-SA 3.0
2015-10-12T23:21:37.290Z
No, atomic counters can only be queried, incremented (by 1) or decremented (by 1). See [the Article](https://www.opengl.org/wiki/Atomic_Counter#Operations) in the opengl wiki. They are not the same as atomic Add etc on Images. You only have 8 (or so) of them and they are supposedly much faster when accessed extremely often (like when generating (and thus counting) thousands of ... things.)
cupe
CC BY-SA 3.0
2015-10-13T00:35:03.507Z
Yeah, I guess you would have to turn it from an "atomic counter" to just a variable in an SSBO. Would be interesting to see if that's actually any slower (it might not be, depending on HW). Other than that, the only thing I can think of is to do like you said and run a compute shader to multiply the value by 3.
Nathan Reed
CC BY-SA 3.0
2016-03-13T18:35:18.960Z
Hi cupe, is it possible to take a look to the code somewhere? Ps: are you checking also for multiple entries?
elect
<opengl><compute-shader>
OpenGL Compute Shader generating triangle indices: How to get correct element count for glDrawElementsIndirect?
cupe
# OpenGL Compute Shader generating triangle indices: How to get correct element count for glDrawElementsIndirect?

(Asked by: username_0 on 2015-10-12)

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](http://docs.gl/gl4/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?

**Tags:** opengl, compute-shader

> **Comments:**
> **username_1**: Can you atomic-add 3 to the counter instead of incrementing it?  
> **username_0**: No, atomic counters can only be queried, incremented (by 1) or decremented (by 1). See [the Article](https://www.opengl.org/wiki/Atomic_Counter#Operations) in the opengl wiki. They are not the same as atomic Add etc on Images. You only have 8 (or so) of them and they are supposedly much faster when accessed extremely often (like when generating (and thus counting) thousands of ... things.)  
> **username_1**: Yeah, I guess you would have to turn it from an "atomic counter" to just a variable in an SSBO. Would be interesting to see if that's actually any slower (it might not be, depending on HW). Other than that, the only thing I can think of is to do like you said and run a compute shader to multiply the value by 3.  
> **username_2**: Hi username_0, is it possible to take a look to the code somewhere? Ps: are you checking also for multiple entries?  

---

## 1 answers

### Answer by username_3 on 2015-10-13. Score: 7 | Accepted answer

If you have access to glsl 4.3+ (or glsl ES 3.1) you can use [atomicAdd](http://docs.gl/sl4/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`.

> **Comments:**
> **username_0**: I like the second idea because it makes clear that I need two different things: A way to atomically add triangles and a way to get the final index count. Doesn't have to be the same mechanism. And yes, I'll try atomicAdd as well. As username_1 suggested in a comment above, it would be interesting to see if it really is slower. I'll report back with the findings.  
> **username_0**: Can confirm that atomicAdd is indeed not slower for this use case on nvidia kepler ( ~1.5k indices: 0.1ms - probably needs larger size for meaningful benchmark). Binding the indirect command buffer as an SSBO and writing to the uint at position 0 works fine. Sometimes one should just try the easy solutions first...  

---

