summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2020-02-10 13:09:37 -0800
committerGitHub <noreply@github.com>2020-02-10 13:09:37 -0800
commit56771d655d77395e4fe879cc19771d461aa01190 (patch)
tree1ea915ae2db4a1e164f2676014c17f8c3c796629
parent60dfb62e638a06ebdcef27138b63033b828ec2ef (diff)
Fix output GLSL for primitive ID in a geometry shader (#1214)
We had been translating an `SV_PrimitiveID` input in a shader over to `gl_PrimitiveID` in GLSL. That translation seemed to work just fine for users, so we thought it was correct. It turns out that `gl_PrimitiveID` is the correct GLSL for a primitive ID input in every stage *except* a geometry shader. In a geometry shader, `gl_PrimitiveID` is a primitive ID *output*, and if you want the input case you have to write `gl_PrimitiveIDIn` (note the `In` suffix). This change sets aside my bewilderment at the above long enough to implement a workaround in the GLSL legalization step. I also modified our current geometry shader cross compilation test to make use of an input primitive ID.
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp31
-rw-r--r--tests/cross-compile/geometry-shader.slang5
-rw-r--r--tests/cross-compile/geometry-shader.slang.glsl16
3 files changed, 41 insertions, 11 deletions
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index 263e56f55..2c889f341 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -414,9 +414,36 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
{
// uint in hlsl, int in glsl
// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/gl_PrimitiveID.xhtml
- name = "gl_PrimitiveID";
-
requiredType = builder->getBasicType(BaseType::Int);
+
+ switch( context->getStage() )
+ {
+ default:
+ name = "gl_PrimitiveID";
+ break;
+
+ case Stage::Geometry:
+ // GLSL makes a confusing design choice here.
+ //
+ // All the non-GS stages use `gl_PrimitiveID` to access
+ // the *input* primitive ID, but a GS uses `gl_PrimitiveID`
+ // to acces an *output* primitive ID (that will be passed
+ // along to the fragment shader).
+ //
+ // For a GS to get an input primitive ID (the thing that
+ // other stages access with `gl_PrimitiveID`), the
+ // programmer must write `gl_PrimitiveIDIn`.
+ //
+ if( kind == LayoutResourceKind::VaryingInput )
+ {
+ name = "gl_PrimitiveIDIn";
+ }
+ else
+ {
+ name = "gl_PrimitiveID";
+ }
+ break;
+ }
}
else if (semanticName == "sv_rendertargetarrayindex")
{
diff --git a/tests/cross-compile/geometry-shader.slang b/tests/cross-compile/geometry-shader.slang
index 614d71db9..8666b739a 100644
--- a/tests/cross-compile/geometry-shader.slang
+++ b/tests/cross-compile/geometry-shader.slang
@@ -19,7 +19,8 @@ struct RasterVertex
[maxvertexcount(3)]
void main(
triangle CoarseVertex coarseVertices[3],
- inout TriangleStream<RasterVertex> outputStream)
+ inout TriangleStream<RasterVertex> outputStream,
+ uint primitiveID : SV_PrimitiveID)
{
for(int ii = 0; ii < 3; ++ii)
{
@@ -27,7 +28,7 @@ void main(
RasterVertex rasterVertex;
rasterVertex.position = coarseVertex.position;
rasterVertex.color = coarseVertex.color;
- rasterVertex.id = coarseVertex.id;
+ rasterVertex.id = coarseVertex.id + primitiveID;
outputStream.Append(rasterVertex);
}
}
diff --git a/tests/cross-compile/geometry-shader.slang.glsl b/tests/cross-compile/geometry-shader.slang.glsl
index cdd0f94de..2dd9d35bc 100644
--- a/tests/cross-compile/geometry-shader.slang.glsl
+++ b/tests/cross-compile/geometry-shader.slang.glsl
@@ -52,13 +52,15 @@ void main()
{
int ii_0;
+ uint _S6 = uint(gl_PrimitiveIDIn);
+
// TODO: Having to make this copy to transpose things is unfortunate.
//
// The front-end should be able to generate code using aggregate
// types for the input, and/or eliminate the redundant temporary
// by indexing directly into the sub-arrays.
//
- CoarseVertex_0 _S6[3] = {
+ CoarseVertex_0 _S7[3] = {
CoarseVertex_0(input_position[0], input_color[0], input_id[0]),
CoarseVertex_0(input_position[1], input_color[1], input_id[1]),
CoarseVertex_0(input_position[2], input_color[2], input_id[2])
@@ -74,18 +76,18 @@ void main()
break;
}
- CoarseVertex_0 coarseVertex_0 = _S6[ii_0];
+ CoarseVertex_0 coarseVertex_0 = _S7[ii_0];
RasterVertex_0 rasterVertex_0;
rasterVertex_0.position_0 = coarseVertex_0.position_1;
rasterVertex_0.color_0 = coarseVertex_0.color_1;
- rasterVertex_0.id_0 = coarseVertex_0.id_1;
+ rasterVertex_0.id_0 = coarseVertex_0.id_1 + _S6;
- RasterVertex_0 _S7 = rasterVertex_0;
+ RasterVertex_0 _S8 = rasterVertex_0;
- output_position = _S7.position_0;
- output_color = _S7.color_0;
- gl_Layer = int(_S7.id_0);
+ output_position = _S8.position_0;
+ output_color = _S8.color_0;
+ gl_Layer = int(_S8.id_0);
EmitVertex();