Browse Source

[spirv] Complete the support for SV semantics in all stages (#775)

Covers the following SVs for all their legal SigPoints:

* SV_Position
* SV_ClipDistance
* SV_CullDistance
* SV_VertexID
* SV_InstanceID
* SV_Depth
* SV_DepthGreaterEqual
* SV_DepthLessEqual
* SV_OutputControlPointID
* SV_DomainLocation
* SV_GSInstanceID
* SV_IsFrontFace
* SV_DispatchTreadID
* SV_GroupID
* SV_GroupThreadID
* SV_GroupIndex
* SV_TessFactor
* SV_InsideTessFactor
* SV_PrimitiveID
* SV_SampleIndex
Lei Zhang 7 years ago
parent
commit
68ef628bd9

+ 69 - 3
docs/SPIR-V.rst

@@ -718,9 +718,53 @@ some system-value (SV) semantic strings will be translated into SPIR-V
 | HLSL Semantic           | SigPoint    | SPIR-V ``BuiltIn``       | SPIR-V Execution Mode |
 +=========================+=============+==========================+=======================+
 |                         | VSOut       | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPIn      | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPOut     | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | DSCPIn      | ``Position``             | N/A                   |
 | SV_Position             +-------------+--------------------------+-----------------------+
+|                         | DSOut       | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSVIn       | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSOut       | ``Position``             | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
 |                         | PSIn        | ``FragCoord``            | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
+|                         | VSOut       | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPIn      | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPOut     | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | DSCPIn      | ``ClipDistance``         | N/A                   |
+| SV_ClipDistance         +-------------+--------------------------+-----------------------+
+|                         | DSOut       | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSVIn       | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSOut       | ``ClipDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | PSIn        | ``ClipDistance``         | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
+|                         | VSOut       | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPIn      | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | HSCPOut     | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | DSCPIn      | ``CullDistance``         | N/A                   |
+| SV_CullDistance         +-------------+--------------------------+-----------------------+
+|                         | DSOut       | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSVIn       | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSOut       | ``CullDistance``         | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | PSIn        | ``CullDistance``         | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
 | SV_VertexID             | VSIn        | ``VertexIndex``          | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
 | SV_InstanceID           | VSIn        | ``InstanceIndex``        | N/A                   |
@@ -731,6 +775,8 @@ some system-value (SV) semantic strings will be translated into SPIR-V
 +-------------------------+-------------+--------------------------+-----------------------+
 | SV_DepthLessEqual       | PSOut       | ``FragDepth``            | ``DepthLess``         |
 +-------------------------+-------------+--------------------------+-----------------------+
+| SV_IsFrontFace          | PSIn        | ``FrontFacing``          | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
 | SV_DispatchThreadID     | CSIn        | ``GlobalInvocationId``   | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
 | SV_GroupID              | CSIn        | ``WorkgroupId``          | N/A                   |
@@ -741,11 +787,31 @@ some system-value (SV) semantic strings will be translated into SPIR-V
 +-------------------------+-------------+--------------------------+-----------------------+
 | SV_OutputControlPointID | HSIn        | ``InvocationId``         | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
-| SV_PrimitiveID          | HSIn / PCIn | ``PrimitiveId``          | N/A                   |
+| SV_GSInstanceID         | GSIn        | ``InvocationId``         | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
+| SV_DomainLocation       | DSIn        | ``TessCoord``            | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
+|                         | HSIn        | ``PrimitiveId``          | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | PCIn        | ``PrimitiveId``          | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | DsIn        | ``PrimitiveId``          | N/A                   |
+| SV_PrimitiveID          +-------------+--------------------------+-----------------------+
+|                         | GSIn        | ``PrimitiveId``          | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | GSOut       | ``PrimitiveId``          | N/A                   |
+|                         +-------------+--------------------------+-----------------------+
+|                         | PSIn        | ``PrimitiveId``          | N/A                   |
++-------------------------+-------------+--------------------------+-----------------------+
+|                         | PCOut       | ``TessLevelOuter``       | N/A                   |
+| SV_TessFactor           +-------------+--------------------------+-----------------------+
+|                         | DSIn        | ``TessLevelOuter``       | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
-| SV_TessFactor           | PCOut       | ``TessLevelOuter``       | N/A                   |
+|                         | PCOut       | ``TessLevelInner``       | N/A                   |
+| SV_InsideTessFactor     +-------------+--------------------------+-----------------------+
+|                         | DSIn        | ``TessLevelInner``       | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
-| SV_InsideTessFactor     | PCOut       | ``TessLevelInner``       | N/A                   |
+| SV_SampleIndex          | PSIn        | ``SampleId``             | N/A                   |
 +-------------------------+-------------+--------------------------+-----------------------+
 
 [TODO] add other SV semantic strings in the above

+ 65 - 11
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -788,7 +788,8 @@ bool DeclResultIdMapper::createStageVars(
                                           shaderModel.GetMajor(),
                                           shaderModel.GetMinor()) ==
         hlsl::DXIL::SemanticInterpretationKind::NA) {
-      emitError("invalid semantic %0 for shader model %1", decl->getLocation())
+      emitError("invalid usage of semantic '%0' in shader profile %1",
+                decl->getLocation())
           << semanticStr << shaderModel.GetName();
       return false;
     }
@@ -1175,10 +1176,13 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
     }
   }
   // According to DXIL spec, the VertexID SV can only be used by VSIn.
-  case hlsl::Semantic::Kind::VertexID:
+  // According to Vulkan spec, the VertexIndex BuiltIn can only be used by
+  // VSIn.
+  case hlsl::Semantic::Kind::VertexID: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::VertexIndex);
-  // According to DXIL spec, the InstanceID SV can  be used by VSIn, VSOut,
+  }
+  // According to DXIL spec, the InstanceID SV can be used by VSIn, VSOut,
   // HSCPIn, HSCPOut, DSCPIn, DSOut, GSVIn, GSOut, PSIn.
   // According to Vulkan spec, the InstanceIndex BuitIn can only be used by
   // VSIn.
@@ -1188,17 +1192,21 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
       stageVar->setIsSpirvBuiltin();
       return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InstanceIndex);
     case hlsl::SigPoint::Kind::VSOut:
-      return theBuilder.addStageIOVar(type, sc, name.str());
+    case hlsl::SigPoint::Kind::HSCPIn:
+    case hlsl::SigPoint::Kind::HSCPOut:
+    case hlsl::SigPoint::Kind::DSCPIn:
+    case hlsl::SigPoint::Kind::DSOut:
+    case hlsl::SigPoint::Kind::GSVIn:
+    case hlsl::SigPoint::Kind::GSOut:
     case hlsl::SigPoint::Kind::PSIn:
       return theBuilder.addStageIOVar(type, sc, name.str());
     default:
-      emitError("semantic InstanceID for SigPoint %0 unimplemented", srcLoc)
-          << sigPoint->GetName();
-      break;
+      llvm_unreachable("invalid usage of SV_InstanceID sneaked in");
     }
   }
   // According to DXIL spec, the Depth{|GreaterEqual|LessEqual} SV can only be
   // used by PSOut.
+  // According to Vulkan spec, the FragDepth BuiltIn can only be used by PSOut.
   case hlsl::Semantic::Kind::Depth:
   case hlsl::Semantic::Kind::DepthGreaterEqual:
   case hlsl::Semantic::Kind::DepthLessEqual: {
@@ -1242,14 +1250,13 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
   // According to Vulkan spec, the FrontFacing BuitIn can only be used in PSIn.
   case hlsl::Semantic::Kind::IsFrontFace: {
     switch (sigPointKind) {
+    case hlsl::SigPoint::Kind::GSOut:
+      return theBuilder.addStageIOVar(type, sc, name.str());
     case hlsl::SigPoint::Kind::PSIn:
       stageVar->setIsSpirvBuiltin();
       return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FrontFacing);
     default:
-      emitError("semantic IsFrontFace for SigPoint %0 unimplemented",
-                srcLoc)
-          << sigPoint->GetName();
-      break;
+      llvm_unreachable("invalid usage of SV_IsFrontFace sneaked in");
     }
   }
   // According to DXIL spec, the Target SV can only be used by PSOut.
@@ -1262,43 +1269,90 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
     return theBuilder.addStageIOVar(type, sc, name.str());
     // TODO: patch constant function in hull shader
   }
+  // According to DXIL spec, the DispatchThreadID SV can only be used by CSIn.
+  // According to Vulkan spec, the GlobalInvocationId can only be used in CSIn.
   case hlsl::Semantic::Kind::DispatchThreadID: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::GlobalInvocationId);
   }
+  // According to DXIL spec, the GroupID SV can only be used by CSIn.
+  // According to Vulkan spec, the WorkgroupId can only be used in CSIn.
   case hlsl::Semantic::Kind::GroupID: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::WorkgroupId);
   }
+  // According to DXIL spec, the GroupThreadID SV can only be used by CSIn.
+  // According to Vulkan spec, the LocalInvocationId can only be used in CSIn.
   case hlsl::Semantic::Kind::GroupThreadID: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::LocalInvocationId);
   }
+  // According to DXIL spec, the GroupIndex SV can only be used by CSIn.
+  // According to Vulkan spec, the LocalInvocationIndex can only be used in
+  // CSIn.
   case hlsl::Semantic::Kind::GroupIndex: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc,
                                          BuiltIn::LocalInvocationIndex);
   }
+  // According to DXIL spec, the OutputControlID SV can only be used by HSIn.
+  // According to Vulkan spec, the InvocationId BuiltIn can only be used in
+  // HS/GS In.
   case hlsl::Semantic::Kind::OutputControlPointID: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
   }
+  // According to DXIL spec, the PrimitiveID SV can only be used by PCIn, HSIn,
+  // DSIn, GSIn, GSOut, and PSIn.
+  // According to Vulkan spec, the PrimitiveId BuiltIn can only be used in
+  // HS/DS/PS In, GS In/Out.
   case hlsl::Semantic::Kind::PrimitiveID: {
+    // PrimitiveId requires either Tessellation or Geometry capability.
+    // Need to require one for PSIn.
+    if (sigPointKind == hlsl::SigPoint::Kind::PSIn)
+      theBuilder.requireCapability(spv::Capability::Tessellation);
+
+    // Translate to PrimitiveId BuiltIn for all valid SigPoints.
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::PrimitiveId);
   }
+  // According to DXIL spec, the TessFactor SV can only be used by PCOut and
+  // DSIn.
+  // According to Vulkan spec, the TessLevelOuter BuiltIn can only be used in
+  // PCOut and DSIn.
   case hlsl::Semantic::Kind::TessFactor: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelOuter);
   }
+  // According to DXIL spec, the InsideTessFactor SV can only be used by PCOut
+  // and DSIn.
+  // According to Vulkan spec, the TessLevelInner BuiltIn can only be used in
+  // PCOut and DSIn.
   case hlsl::Semantic::Kind::InsideTessFactor: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessLevelInner);
   }
+  // According to DXIL spec, the DomainLocation SV can only be used by DSIn.
+  // According to Vulkan spec, the TessCoord BuiltIn can only be used in DSIn.
   case hlsl::Semantic::Kind::DomainLocation: {
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::TessCoord);
   }
+  // According to DXIL spec, the GSInstanceID SV can only be used by GSIn.
+  // According to Vulkan spec, the InvocationId BuiltIn can only be used in
+  // HS/GS In.
+  case hlsl::Semantic::Kind::GSInstanceID: {
+    stageVar->setIsSpirvBuiltin();
+    return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::InvocationId);
+  }
+  // According to DXIL spec, the SampleIndex SV can only be used by PSIn.
+  // According to Vulkan spec, the SampleId BuiltIn can only be used in PSIn.
+  case hlsl::Semantic::Kind::SampleIndex: {
+    theBuilder.requireCapability(spv::Capability::SampleRateShading);
+
+    stageVar->setIsSpirvBuiltin();
+    return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleId);
+  }
   default:
     emitError("semantic %0 unimplemented", srcLoc)
         << stageVar->getSemantic()->GetName();

+ 30 - 0
tools/clang/test/CodeGenSPIRV/semantic.gs-instance-id.gs.hlsl

@@ -0,0 +1,30 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK:      OpEntryPoint Geometry %main "main"
+// CHECK-SAME: %gl_InvocationID
+
+// CHECK:      OpDecorate %gl_InvocationID BuiltIn InvocationId
+
+// CHECK:      %gl_InvocationID = OpVariable %_ptr_Input_uint Input
+
+// GS per-vertex input
+struct GsVIn {
+    float4 foo : FOO;
+};
+
+// GS per-vertex output
+struct GsVOut {
+    float4 bar : BAR;
+};
+
+[maxvertexcount(2)]
+void main(in    line GsVIn              inData[2],
+                     uint               id         : SV_GSInstanceID,
+          inout      LineStream<GsVOut> outData) {
+
+    GsVOut vertex;
+    vertex = (GsVOut)0;
+    outData.Append(vertex);
+
+    outData.RestartStrip();
+}

+ 35 - 0
tools/clang/test/CodeGenSPIRV/semantic.instance-id.ds.hlsl

@@ -0,0 +1,35 @@
+// Run: %dxc -T ds_6_0 -E main
+
+// HS PCF output
+struct HsPcfOut {
+  float  outTessFactor[4]   : SV_TessFactor;
+  float  inTessFactor[2]    : SV_InsideTessFactor;
+};
+
+// Per-vertex input structs
+struct DsCpIn {
+    int id : SV_InstanceID;
+};
+
+// Per-vertex output structs
+struct DsCpOut {
+    int id : SV_InstanceID;
+};
+
+// CHECK:      OpEntryPoint TessellationEvaluation %main "main"
+// CHECK-SAME: %in_var_SV_InstanceID
+// CHECK-SAME: %out_var_SV_InstanceID
+
+
+// CHECK:      OpDecorate %in_var_SV_InstanceID Location 0
+// CHECK:      OpDecorate %out_var_SV_InstanceID Location 0
+
+// CHECK:      %in_var_SV_InstanceID = OpVariable %_ptr_Input__arr_int_uint_3 Input
+// CHECK:      %out_var_SV_InstanceID = OpVariable %_ptr_Output_int Output
+
+[domain("quad")]
+DsCpOut main(OutputPatch<DsCpIn, 3> patch, HsPcfOut pcfData) {
+  DsCpOut dsOut;
+  dsOut = (DsCpOut)0;
+  return dsOut;
+}

+ 33 - 0
tools/clang/test/CodeGenSPIRV/semantic.instance-id.gs.hlsl

@@ -0,0 +1,33 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK:      OpEntryPoint Geometry %main "main"
+// CHECK-SAME: %in_var_SV_InstanceID
+// CHECK-SAME: %out_var_SV_InstanceID
+
+
+// CHECK:      OpDecorate %in_var_SV_InstanceID Location 0
+// CHECK:      OpDecorate %out_var_SV_InstanceID Location 0
+
+// CHECK:      %in_var_SV_InstanceID = OpVariable %_ptr_Input__arr_int_uint_2 Input
+// CHECK:      %out_var_SV_InstanceID = OpVariable %_ptr_Output_int Output
+
+// GS per-vertex input
+struct GsVIn {
+    int id : SV_InstanceID;
+};
+
+// GS per-vertex output
+struct GsVOut {
+    int id : SV_InstanceID;
+};
+
+[maxvertexcount(2)]
+void main(in    line GsVIn              inData[2],
+          inout      LineStream<GsVOut> outData) {
+
+    GsVOut vertex;
+    vertex = (GsVOut)0;
+    outData.Append(vertex);
+
+    outData.RestartStrip();
+}

+ 45 - 0
tools/clang/test/CodeGenSPIRV/semantic.instance-id.hs.hlsl

@@ -0,0 +1,45 @@
+// Run: %dxc -T hs_6_0 -E main
+
+#define NumOutPoints 2
+
+// CHECK:      OpEntryPoint TessellationControl %main "main"
+// CHECK-SAME: %in_var_SV_InstanceID
+// CHECK-SAME: %out_var_SV_InstanceID
+
+// CHECK:      OpDecorate %in_var_SV_InstanceID Location 0
+// CHECK:      OpDecorate %out_var_SV_InstanceID Location 0
+
+// CHECK:      %in_var_SV_InstanceID = OpVariable %_ptr_Input__arr_int_uint_2 Input
+// CHECK:      %out_var_SV_InstanceID = OpVariable %_ptr_Output__arr_int_uint_2 Output
+
+struct HsCpIn {
+    int id : SV_InstanceID;
+};
+
+struct HsCpOut {
+    int id : SV_InstanceID;
+};
+
+struct HsPcfOut {
+  float tessOuter[4] : SV_TessFactor;
+  float tessInner[2] : SV_InsideTessFactor;
+};
+
+// Patch Constant Function
+HsPcfOut pcf() {
+  HsPcfOut output;
+  output = (HsPcfOut)0;
+  return output;
+}
+
+[domain("quad")]
+[partitioning("fractional_odd")]
+[outputtopology("triangle_ccw")]
+[outputcontrolpoints(NumOutPoints)]
+[patchconstantfunc("pcf")]
+HsCpOut main(InputPatch<HsCpIn, NumOutPoints> patch,
+             uint id : SV_OutputControlPointID) {
+    HsCpOut output;
+    output = (HsCpOut)0;
+    return output;
+}

+ 4 - 3
tools/clang/test/CodeGenSPIRV/semantic.instance-id.ps.hlsl

@@ -1,10 +1,11 @@
 // Run: %dxc -T ps_6_0 -E main
 
-// CHECK:             OpEntryPoint Fragment %main "main" %in_var_SV_InstanceID %out_var_SV_Target
+// CHECK:      OpEntryPoint Fragment %main "main"
+// CHECK-SAME: %in_var_SV_InstanceID
 
-// CHECK:             OpDecorate %in_var_SV_InstanceID Location 0
+// CHECK:      OpDecorate %in_var_SV_InstanceID Location 0
 
-// CHECK: %in_var_SV_InstanceID = OpVariable %_ptr_Input_int Input
+// CHECK:      %in_var_SV_InstanceID = OpVariable %_ptr_Input_int Input
 
 float4 main(int input: SV_InstanceID) : SV_Target {
     return input;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/semantic.instance-id.vs.hlsl

@@ -2,6 +2,7 @@
 
 // CHECK:                     OpEntryPoint Vertex %main "main"
 // CHECK-SAME:                %gl_InstanceIndex
+// CHECK-SAME:                %out_var_SV_InstanceID
 
 // CHECK:                     OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
 // CHECK:                     OpDecorate %out_var_SV_InstanceID Location 0

+ 29 - 0
tools/clang/test/CodeGenSPIRV/semantic.is-front-face.gs.hlsl

@@ -0,0 +1,29 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK:      OpEntryPoint Geometry %main "main"
+// CHECK-SAME: %out_var_SV_IsFrontFace
+
+// CHECK:      OpDecorate %out_var_SV_IsFrontFace Location 0
+
+// CHECK:      %out_var_SV_IsFrontFace = OpVariable %_ptr_Output_bool Output
+
+// GS per-vertex input
+struct GsVIn {
+    float4 foo : FOO;
+};
+
+// GS per-vertex output
+struct GsVOut {
+    bool frontFace : SV_IsFrontFace;
+};
+
+[maxvertexcount(2)]
+void main(in    line GsVIn              inData[2],
+          inout      LineStream<GsVOut> outData) {
+
+    GsVOut vertex;
+    vertex = (GsVOut)0;
+    outData.Append(vertex);
+
+    outData.RestartStrip();
+}

+ 31 - 0
tools/clang/test/CodeGenSPIRV/semantic.primitive-id.ds.hlsl

@@ -0,0 +1,31 @@
+// Run: %dxc -T ds_6_0 -E main
+
+// HS PCF output
+struct HsPcfOut {
+  float  outTessFactor[4]   : SV_TessFactor;
+  float  inTessFactor[2]    : SV_InsideTessFactor;
+};
+
+// Per-vertex input structs
+struct DsCpIn {
+    float4 foo : FOO;
+};
+
+// Per-vertex output structs
+struct DsCpOut {
+    float4 bar : BAR;
+};
+
+// CHECK:      OpEntryPoint TessellationEvaluation %main "main"
+// CHECK-SAME: %gl_PrimitiveID
+
+// CHECK:      OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
+
+// CHECK:      %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
+
+[domain("quad")]
+DsCpOut main(OutputPatch<DsCpIn, 3> patch, HsPcfOut pcfData, uint id : SV_PrimitiveID) {
+  DsCpOut dsOut;
+  dsOut = (DsCpOut)0;
+  return dsOut;
+}

+ 33 - 0
tools/clang/test/CodeGenSPIRV/semantic.primitive-id.gs.hlsl

@@ -0,0 +1,33 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK:      OpEntryPoint Geometry %main "main"
+// CHECK-SAME: %gl_PrimitiveID
+// CHECK-SAME: %gl_PrimitiveID_0
+
+// CHECK:      OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
+// CHECK:      OpDecorate %gl_PrimitiveID_0 BuiltIn PrimitiveId
+
+// CHECK:      %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
+// CHECK:      %gl_PrimitiveID_0 = OpVariable %_ptr_Output_uint Output
+
+// GS per-vertex input
+struct GsVIn {
+    float4 foo : FOO;
+};
+
+// GS per-vertex output
+struct GsVOut {
+    uint outId : SV_PrimitiveID;
+};
+
+[maxvertexcount(2)]
+void main(in    line GsVIn              inData[2],
+                     uint               inId     : SV_PrimitiveID,
+          inout      LineStream<GsVOut> outData) {
+
+    GsVOut vertex;
+    vertex = (GsVOut)0;
+    outData.Append(vertex);
+
+    outData.RestartStrip();
+}

+ 14 - 0
tools/clang/test/CodeGenSPIRV/semantic.primitive-id.ps.hlsl

@@ -0,0 +1,14 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK: OpCapability Tessellation
+
+// CHECK:      OpEntryPoint Fragment %main "main"
+// CHECK-SAME: %gl_PrimitiveID
+
+// CHECK:      OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
+
+// CHECK:      %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
+
+float4 main(uint id : SV_PrimitiveID) : SV_Target {
+    return id;
+}

+ 14 - 0
tools/clang/test/CodeGenSPIRV/semantic.sample-index.ps.hlsl

@@ -0,0 +1,14 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK:      OpCapability SampleRateShading
+
+// CHECK:      OpEntryPoint Fragment %main "main"
+// CHECK-SAME: %gl_SampleID
+
+// CEHCK:      OpDecorate %gl_SampleID BuiltIn SampleId
+
+// CHECK:      %gl_SampleID = OpVariable %_ptr_Input_uint Input
+
+float4 main(uint index : SV_SampleIndex) : SV_Target {
+    return 1.0;
+}

+ 0 - 2
tools/clang/test/CodeGenSPIRV/spirv.interface.hs.hlsl

@@ -1,7 +1,5 @@
 // Run: %dxc -T hs_6_0 -E main
 
-// TODO: Handle the Patch decoration
-
 #define NumOutPoints 2
 
 // CHECK: OpCapability ClipDistance

+ 12 - 2
tools/clang/test/CodeGenSPIRV/spirv.interface.vs.hlsl

@@ -3,7 +3,7 @@
 // CHECK: OpCapability ClipDistance
 // CHECK: OpCapability CullDistance
 
-// CHECK: OpEntryPoint Vertex %main "main" %gl_PerVertexOut %in_var_TEXCOORD %in_var_SV_Position %out_var_COLOR %out_var_TEXCOORD
+// CHECK: OpEntryPoint Vertex %main "main" %gl_PerVertexOut %in_var_TEXCOORD %in_var_SV_Position %in_var_SV_ClipDistance %in_var_SV_CullDistance0 %out_var_COLOR %out_var_TEXCOORD
 
 // CHECK: OpMemberDecorate %type_gl_PerVertex 0 BuiltIn Position
 // CHECK: OpMemberDecorate %type_gl_PerVertex 1 BuiltIn PointSize
@@ -13,6 +13,8 @@
 
 // CHECK: OpDecorate %in_var_TEXCOORD Location 0
 // CHECK: OpDecorate %in_var_SV_Position Location 1
+// CHECK: OpDecorate %in_var_SV_ClipDistance Location 2
+// CHECK: OpDecorate %in_var_SV_CullDistance0 Location 3
 // CHECK: OpDecorate %out_var_COLOR Location 0
 // CHECK: OpDecorate %out_var_TEXCOORD Location 1
 
@@ -24,6 +26,8 @@
 
 // CHECK: %in_var_TEXCOORD = OpVariable %_ptr_Input_v4float Input
 // CHECK: %in_var_SV_Position = OpVariable %_ptr_Input_v4float Input
+// CHECK: %in_var_SV_ClipDistance = OpVariable %_ptr_Input_v2float Input
+// CHECK: %in_var_SV_CullDistance0 = OpVariable %_ptr_Input_v3float Input
 // CHECK: %out_var_COLOR = OpVariable %_ptr_Output_v4float Output
 // CHECK: %out_var_TEXCOORD = OpVariable %_ptr_Output_v4float Output
 
@@ -47,7 +51,9 @@ void main(out VSOut  vsOut,
           out   float  culldis5 : SV_CullDistance5, // -> BuiltIn CullDistance in gl_PerVertex
           out   float  culldis3 : SV_CullDistance3, // -> BuiltIn CullDistance in gl_PerVertex
           out   float  culldis6 : SV_CullDistance6, // -> BuiltIn CullDistance in gl_PerVertex
-          in    float4 inPos    : SV_Position       // -> Input variable
+          in    float4 inPos    : SV_Position,      // -> Input variable
+          in    float2 inClip   : SV_ClipDistance,  // -> Input variable
+          in    float3 inCull   : SV_CullDistance0  // -> Input variable
          ) {
     vsOut    = (VSOut)0;
     clipdis0 = 1.;
@@ -70,6 +76,10 @@ void main(out VSOut  vsOut,
 // CHECK-NEXT:                     OpStore %param_var_coord [[texcoord]]
 // CHECK-NEXT:      [[pos:%\d+]] = OpLoad %v4float %in_var_SV_Position
 // CHECK-NEXT:                     OpStore %param_var_inPos [[pos]]
+// CHECK-NEXT:   [[inClip:%\d+]] = OpLoad %v2float %in_var_SV_ClipDistance
+// CHECK-NEXT:                     OpStore %param_var_inClip [[inClip]]
+// CHECK-NEXT:   [[inCull:%\d+]] = OpLoad %v3float %in_var_SV_CullDistance0
+// CHECK-NEXT:                     OpStore %param_var_inCull [[inCull]]
 
 // CHECK-NEXT: OpFunctionCall %void %src_main
 

+ 27 - 0
tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp

@@ -359,6 +359,15 @@ TEST_F(FileTest, SemanticVertexIDVS) {
 TEST_F(FileTest, SemanticInstanceIDVS) {
   runFileTest("semantic.instance-id.vs.hlsl");
 }
+TEST_F(FileTest, SemanticInstanceIDHS) {
+  runFileTest("semantic.instance-id.hs.hlsl");
+}
+TEST_F(FileTest, SemanticInstanceIDDS) {
+  runFileTest("semantic.instance-id.ds.hlsl");
+}
+TEST_F(FileTest, SemanticInstanceIDGS) {
+  runFileTest("semantic.instance-id.gs.hlsl");
+}
 TEST_F(FileTest, SemanticInstanceIDPS) {
   runFileTest("semantic.instance-id.ps.hlsl");
 }
@@ -370,6 +379,9 @@ TEST_F(FileTest, SemanticDepthGreaterEqualPS) {
 TEST_F(FileTest, SemanticDepthLessEqualPS) {
   runFileTest("semantic.depth-less-equal.ps.hlsl");
 }
+TEST_F(FileTest, SemanticIsFrontFaceGS) {
+  runFileTest("semantic.is-front-face.gs.hlsl");
+}
 TEST_F(FileTest, SemanticIsFrontFacePS) {
   runFileTest("semantic.is-front-face.ps.hlsl");
 }
@@ -417,9 +429,24 @@ TEST_F(FileTest, SemanticInsideTessFactorHS) {
 TEST_F(FileTest, SemanticPrimitiveIdHS) {
   runFileTest("semantic.primitive-id.hs.hlsl");
 }
+TEST_F(FileTest, SemanticPrimitiveIdDS) {
+  runFileTest("semantic.primitive-id.ds.hlsl");
+}
+TEST_F(FileTest, SemanticPrimitiveIdGS) {
+  runFileTest("semantic.primitive-id.gs.hlsl");
+}
+TEST_F(FileTest, SemanticPrimitiveIdPS) {
+  runFileTest("semantic.primitive-id.ps.hlsl");
+}
 TEST_F(FileTest, SemanticOutputControlPointIdHS) {
   runFileTest("semantic.output-control-point-id.hs.hlsl");
 }
+TEST_F(FileTest, SemanticGSInstanceIDGS) {
+  runFileTest("semantic.gs-instance-id.gs.hlsl");
+}
+TEST_F(FileTest, SemanticSampleIndexPS) {
+  runFileTest("semantic.sample-index.ps.hlsl");
+}
 
 // For texture methods
 TEST_F(FileTest, TextureSample) { runFileTest("texture.sample.hlsl"); }