diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2020-02-10 13:09:37 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-10 13:09:37 -0800 |
| commit | 56771d655d77395e4fe879cc19771d461aa01190 (patch) | |
| tree | 1ea915ae2db4a1e164f2676014c17f8c3c796629 | |
| parent | 60dfb62e638a06ebdcef27138b63033b828ec2ef (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.cpp | 31 | ||||
| -rw-r--r-- | tests/cross-compile/geometry-shader.slang | 5 | ||||
| -rw-r--r-- | tests/cross-compile/geometry-shader.slang.glsl | 16 |
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(); |
