<p>It seems likely that the mechanism by which the <code>gl_PrimitiveID</code> is generated is, in some way, based on the hardware that makes geometry shaders possible.</p>

<p>OpenGL ES 3.1 contains compute shaders but not geometry shaders (or tessellation). But it doesn't have <code>gl_PrimitiveID</code>. By contrast, ES 3.2 contains GS's and <code>gl_PrimitiveID</code>. The same goes for desktop OpenGL 3.1 vs. 3.2 and its GS functionality. Having a GS and having the ability to identify primitives in a sequence seem to be part of the same general functionality.</p>

<blockquote>
  <p>In my pipeline I used gl_PrimitiveID to fetch per-face data from global ssbo and to render face ids to attachment for later reuse.</p>
</blockquote>

<p>Without the hardware functionality, there is no <em>general</em> way to compute a count of primitives. There are only specific solutions for specific circumstances.</p>

<p>For example, if you are using non-index rendering of triangle lists, then you can use <code>gl_VertexID / 3</code> to compute a primitive ID. Obviously that's a pretty tight restriction, but it would work in that circumstance.</p>

<p>You could also provide each vertex with a per-vertex face ID. The VS would output this value using <code>flat</code> interpolation. By carefully matching the face ID with the <a href="https://www.khronos.org/registry/vulkan/specs/1.1/html/chap19.html#drawing-primitive-topologies" rel="nofollow noreferrer">provoking vertex for the primitive topology</a>, you can effectively assign a face ID to a face. This works best with indexed triangle lists, as you can play around with the order of indices in a triangle more than you can with strips. You basically have to decide which vertex maps to which face, and make sure that that face uses that vertex as the first one.</p>

CC BY-SA 4.0
2020-03-06T19:28:56.973Z
The idea of using the VS in combination with the provoking vertex is attractive but in most cases it is not possible. The reason is that even for the most simple type of regular triangular mesh, asymptotically, there are twice as many triangles as there are vertices. 
Mathematically, you would need to build a mesh that has at most as many triangles as there are vertices. To fill a 2D flat space, since every vertex would  have 3 triangles connected to it on average, the average angle of each triangle summit is 120°. That's not possible since the sum of angles in a triangle is 180°.
Michel
CC BY-SA 4.0
2019-12-29T17:02:11.097Z
2019-12-29T17:02:11.097Z
Nicol Bolas
<p>When compiling a glsl fragment shader which reads <code>gl_PrimitiveID</code> with glslc compiler I get the spirv-1.0 with Geometry capability enabled, which is technically correct, as it's stated in spirv spec. 
Vulkan 1.0 spec says that Geometry capability must be supported if <code>geometryShader</code> feature is enabled. </p>

<p>So I assume that unless <code>geometryShader</code> is enabled, one can't use <code>gl_PrimitiveID</code>. Specifically, using <code>gl_PrimitiveID</code> is impossible on moltenVK, as it does not support this feature, isn't it?</p>

<p>In my pipeline I used <code>gl_PrimitiveID</code> to fetch per-face data from global ssbo and to render face ids to attachment for later reuse. Is it possible to achieve similar result without <code>gl_PrimitiveID</code>?</p>

CC BY-SA 4.0
2019-12-29T16:48:37.340Z
@httpdigest: It also only works for drawing triangle lists.
Nicol Bolas
CC BY-SA 4.0
2020-03-07T17:27:40.523Z
How do you see that SPIR-V specs say that geometry capability must be supported to have PrimitiveID? The specs say that PrimitiveID is enable by either of Geometry or Tesselation. So it seems that turning on geometry is over the requirements. I am running on MoltenVK which does not support geometry but supports tesselation. Use of gl_PrimitiveID triggers a warning in the validation layers about geometry being flagged yet not available. However gl_PrimitiveID does work. This lead me to this discussion.
Michel
<vulkan>
Vulkan: using gl_PrimitiveID without geometryShader feature
Vladimir Nazarenko
# Vulkan: using gl_PrimitiveID without geometryShader feature

(Asked by: username_0 on 2019-12-28)

When compiling a glsl fragment shader which reads `gl_PrimitiveID` with glslc compiler I get the spirv-1.0 with Geometry capability enabled, which is technically correct, as it's stated in spirv spec.
Vulkan 1.0 spec says that Geometry capability must be supported if `geometryShader` feature is enabled.

So I assume that unless `geometryShader` is enabled, one can't use `gl_PrimitiveID`. Specifically, using `gl_PrimitiveID` is impossible on moltenVK, as it does not support this feature, isn't it?

In my pipeline I used `gl_PrimitiveID` to fetch per-face data from global ssbo and to render face ids to attachment for later reuse. Is it possible to achieve similar result without `gl_PrimitiveID`?

**Tags:** vulkan

> **Comments:**
> **username_1**: @httpdigest: It also only works for drawing triangle lists.  
> **username_2**: How do you see that SPIR-V specs say that geometry capability must be supported to have PrimitiveID? The specs say that PrimitiveID is enable by either of Geometry or Tesselation. So it seems that turning on geometry is over the requirements. I am running on MoltenVK which does not support geometry but supports tesselation. Use of gl_PrimitiveID triggers a warning in the validation layers about geometry being flagged yet not available. However gl_PrimitiveID does work. This lead me to this discussion.  

---

## 1 answers

### Answer by username_1 on 2019-12-29. Score: 1 | Accepted answer

It seems likely that the mechanism by which the `gl_PrimitiveID` is generated is, in some way, based on the hardware that makes geometry shaders possible.

OpenGL ES 3.1 contains compute shaders but not geometry shaders (or tessellation). But it doesn't have `gl_PrimitiveID`. By contrast, ES 3.2 contains GS's and `gl_PrimitiveID`. The same goes for desktop OpenGL 3.1 vs. 3.2 and its GS functionality. Having a GS and having the ability to identify primitives in a sequence seem to be part of the same general functionality.

> In my pipeline I used gl\_PrimitiveID to fetch per-face data from global ssbo and to render face ids to attachment for later reuse.

Without the hardware functionality, there is no *general* way to compute a count of primitives. There are only specific solutions for specific circumstances.

For example, if you are using non-index rendering of triangle lists, then you can use `gl_VertexID / 3` to compute a primitive ID. Obviously that's a pretty tight restriction, but it would work in that circumstance.

You could also provide each vertex with a per-vertex face ID. The VS would output this value using `flat` interpolation. By carefully matching the face ID with the [provoking vertex for the primitive topology](https://www.khronos.org/registry/vulkan/specs/1.1/html/chap19.html#drawing-primitive-topologies), you can effectively assign a face ID to a face. This works best with indexed triangle lists, as you can play around with the order of indices in a triangle more than you can with strips. You basically have to decide which vertex maps to which face, and make sure that that face uses that vertex as the first one.

> **Comments:**
> **username_2**: The idea of using the VS in combination with the provoking vertex is attractive but in most cases it is not possible. The reason is that even for the most simple type of regular triangular mesh, asymptotically, there are twice as many triangles as there are vertices.  Mathematically, you would need to build a mesh that has at most as many triangles as there are vertices. To fill a 2D flat space, since every vertex would  have 3 triangles connected to it on average, the average angle of each triangle summit is 120°. That's not possible since the sum of angles in a triangle is 180°.  

---

