diff --git a/docs/user-guide/a2-01-spirv-target-specific.md b/docs/user-guide/a2-01-spirv-target-specific.md index 048318a09a..4faf3bde5d 100644 --- a/docs/user-guide/a2-01-spirv-target-specific.md +++ b/docs/user-guide/a2-01-spirv-target-specific.md @@ -43,6 +43,7 @@ The system-value semantics are translated to the following SPIR-V code. | `SV_DepthLessEqual` | `BuiltIn FragDepth` | | `SV_DispatchThreadID` | `BuiltIn GlobalInvocationId` | | `SV_DomainLocation` | `BuiltIn TessCoord` | +| `SV_DrawIndex` | `Builtin DrawIndex` | | `SV_GSInstanceID` | `BuiltIn InvocationId` | | `SV_GroupID` | `BuiltIn WorkgroupId` | | `SV_GroupIndex` | `BuiltIn LocalInvocationIndex` | @@ -68,7 +69,7 @@ The system-value semantics are translated to the following SPIR-V code. | `SV_ViewID` | `BuiltIn ViewIndex` | | `SV_ViewportArrayIndex` | `BuiltIn ViewportIndex` | -*Note* that `SV_PointSize` is a Slang-specific semantic that is not defined in HLSL. +*Note* that `SV_DrawIndex` and `SV_PointSize` are Slang-specific semantics that are not defined in HLSL. Behavior of `discard` after SPIR-V 1.6 diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 6c525d064a..f224191475 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -1127,6 +1127,10 @@ void GLSLSourceEmitter::_maybeEmitGLSLBuiltin(IRGlobalParam* var, UnownedStringS { _requireGLSLExtension(toSlice("GL_EXT_fragment_shading_rate_primitive")); } + else if (name == "gl_DrawID") + { + _requireGLSLVersion(460); + } } void GLSLSourceEmitter::_requireBaseType(BaseType baseType) diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 58f5e4f666..f4aa900dbb 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -5137,6 +5137,11 @@ struct SPIRVEmitContext : public SourceEmitterBase, public SPIRVEmitSharedContex // float in hlsl & glsl return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInPointSize, inst); } + else if (semanticName == "sv_drawindex") + { + requireSPIRVCapability(SpvCapabilityDrawParameters); + return getBuiltinGlobalVar(inst->getFullType(), SpvBuiltInDrawIndex, inst); + } else if (semanticName == "sv_primitiveid") { auto entryPoints = m_referencingEntryPoints.tryGetValue(inst); diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp index 3f3f2dbe03..619682692b 100644 --- a/source/slang/slang-ir-glsl-legalize.cpp +++ b/source/slang/slang-ir-glsl-legalize.cpp @@ -623,6 +623,11 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo( name = "gl_PointSize"; requiredType = builder->getBasicType(BaseType::Float); } + else if (semanticName == "sv_drawindex") + { + name = "gl_DrawID"; + requiredType = builder->getBasicType(BaseType::Int); + } else if (semanticName == "sv_primitiveid") { // uint in hlsl, int in glsl diff --git a/source/slang/slang-ir-legalize-varying-params.h b/source/slang/slang-ir-legalize-varying-params.h index 3c97d739b1..c8952f6045 100644 --- a/source/slang/slang-ir-legalize-varying-params.h +++ b/source/slang/slang-ir-legalize-varying-params.h @@ -48,6 +48,7 @@ IRInst* emitCalcGroupIndex(IRBuilder& builder, IRInst* groupThreadID, IRInst* gr M(OutputControlPointID, SV_OutputControlPointID) \ M(PointSize, SV_PointSize) \ M(PrimitiveID, SV_PrimitiveID) \ + M(DrawIndex, SV_DrawIndex) \ M(RenderTargetArrayIndex, SV_RenderTargetArrayIndex) \ M(SampleIndex, SV_SampleIndex) \ M(StencilRef, SV_StencilRef) \ diff --git a/source/slang/slang-language-server-completion.cpp b/source/slang/slang-language-server-completion.cpp index 82b7286eaa..03c6b88ed3 100644 --- a/source/slang/slang-language-server-completion.cpp +++ b/source/slang/slang-language-server-completion.cpp @@ -116,6 +116,7 @@ static const char* hlslSemanticNames[] = { "SV_Position", "SV_PointSize", "SV_PrimitiveID", + "SV_DrawIndex", "SV_RenderTargetArrayIndex", "SV_SampleIndex", "SV_StencilRef", diff --git a/tests/spirv/draw-index.slang b/tests/spirv/draw-index.slang new file mode 100644 index 0000000000..9020eb8b49 --- /dev/null +++ b/tests/spirv/draw-index.slang @@ -0,0 +1,18 @@ +//TEST:SIMPLE(filecheck=SPIRV): -target spirv +//TEST:SIMPLE(filecheck=SPIRV): -target spirv -entry vsMain -stage vertex -emit-spirv-via-glsl +//TEST:SIMPLE(filecheck=GLSL): -target glsl -entry vsMain -stage vertex + +// SPIRV: OpDecorate %{{.*}} BuiltIn DrawIndex +// GLSL: gl_DrawID + +struct VertexIn +{ + float3 position; + int drawIndex : SV_DrawIndex; +} + +[shader("vertex")] +float4 vsMain(VertexIn vin) : SV_Position +{ + return float4(vin.position, vin.drawIndex); +}