Jelajahi Sumber

[spirv] Support SV_RenderTargetArrayIndex and SV_StencilRef (#789)

Lei Zhang 7 tahun lalu
induk
melakukan
e9a2c759b5

+ 105 - 99
docs/SPIR-V.rst

@@ -728,105 +728,111 @@ some system-value (SV) semantic strings will be translated into SPIR-V
 
 .. table:: Mapping from HLSL SV semantic to SPIR-V builtin and execution mode
 
-+-------------------------+-------------+--------------------------+-----------------------+
-| 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                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_Depth                | PSOut       | ``FragDepth``            | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_DepthGreaterEqual    | PSOut       | ``FragDepth``            | ``DepthGreater``      |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_DepthLessEqual       | PSOut       | ``FragDepth``            | ``DepthLess``         |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_IsFrontFace          | PSIn        | ``FrontFacing``          | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_DispatchThreadID     | CSIn        | ``GlobalInvocationId``   | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_GroupID              | CSIn        | ``WorkgroupId``          | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_GroupThreadID        | CSIn        | ``LocalInvocationId``    | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_GroupIndex           | CSIn        | ``LocalInvocationIndex`` | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_OutputControlPointID | HSIn        | ``InvocationId``         | 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                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-|                         | PCOut       | ``TessLevelInner``       | N/A                   |
-| SV_InsideTessFactor     +-------------+--------------------------+-----------------------+
-|                         | DSIn        | ``TessLevelInner``       | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
-| SV_SampleIndex          | PSIn        | ``SampleId``             | N/A                   |
-+-------------------------+-------------+--------------------------+-----------------------+
++---------------------------+-------------+--------------------------+-----------------------+
+| 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                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_Depth                  | PSOut       | ``FragDepth``            | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_DepthGreaterEqual      | PSOut       | ``FragDepth``            | ``DepthGreater``      |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_DepthLessEqual         | PSOut       | ``FragDepth``            | ``DepthLess``         |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_IsFrontFace            | PSIn        | ``FrontFacing``          | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_DispatchThreadID       | CSIn        | ``GlobalInvocationId``   | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_GroupID                | CSIn        | ``WorkgroupId``          | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_GroupThreadID          | CSIn        | ``LocalInvocationId``    | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_GroupIndex             | CSIn        | ``LocalInvocationIndex`` | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_OutputControlPointID   | HSIn        | ``InvocationId``         | 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                   |
++---------------------------+-------------+--------------------------+-----------------------+
+|                           | PCOut       | ``TessLevelInner``       | N/A                   |
+| SV_InsideTessFactor       +-------------+--------------------------+-----------------------+
+|                           | DSIn        | ``TessLevelInner``       | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_SampleIndex            | PSIn        | ``SampleId``             | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+| SV_StencilRef             | PSOut       | ``FragStencilRefEXT``    | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
+|                           | GSOut       | ``Layer``                | N/A                   |
+| SV_RenderTargetArrayIndex +-------------+--------------------------+-----------------------+
+|                           | PSIn        | ``Layer``                | N/A                   |
++---------------------------+-------------+--------------------------+-----------------------+
 
 [TODO] add other SV semantic strings in the above
 

+ 7 - 0
tools/clang/include/clang/SPIRV/ModuleBuilder.h

@@ -279,6 +279,9 @@ public:
   void addExecutionMode(uint32_t entryPointId, spv::ExecutionMode em,
                         llvm::ArrayRef<uint32_t> params);
 
+  /// \brief Adds an extension to the module under construction.
+  inline void addExtension(llvm::StringRef extension);
+
   /// \brief If not added already, adds an OpExtInstImport (import of extended
   /// instruction set) of the GLSL instruction set. Returns the <result-id> for
   /// the imported GLSL instruction set.
@@ -416,6 +419,10 @@ void ModuleBuilder::addEntryPoint(spv::ExecutionModel em, uint32_t targetId,
   theModule.addEntryPoint(em, targetId, std::move(targetName), interfaces);
 }
 
+void ModuleBuilder::addExtension(llvm::StringRef extension) {
+  theModule.addExtension(extension);
+}
+
 } // end namespace spirv
 } // end namespace clang
 

+ 4 - 4
tools/clang/include/clang/SPIRV/Structure.h

@@ -296,7 +296,7 @@ public:
   inline void setBound(uint32_t newBound);
 
   inline void addCapability(spv::Capability);
-  inline void addExtension(std::string extension);
+  inline void addExtension(llvm::StringRef extension);
   inline void addExtInstSet(uint32_t setId, llvm::StringRef extInstSet);
   inline void setAddressingModel(spv::AddressingModel);
   inline void setMemoryModel(spv::MemoryModel);
@@ -338,7 +338,7 @@ private:
 private:
   Header header; ///< SPIR-V module header.
   llvm::SetVector<spv::Capability> capabilities;
-  std::vector<std::string> extensions;
+  llvm::SetVector<std::string> extensions;
   llvm::MapVector<const char *, uint32_t> extInstSets;
   // Addressing and memory model must exist for a valid SPIR-V module.
   // We make them optional here just to provide extra flexibility of
@@ -457,8 +457,8 @@ void SPIRVModule::addCapability(spv::Capability cap) {
   capabilities.insert(cap);
 }
 
-void SPIRVModule::addExtension(std::string ext) {
-  extensions.push_back(std::move(ext));
+void SPIRVModule::addExtension(llvm::StringRef ext) {
+  extensions.insert(ext.str());
 }
 
 uint32_t SPIRVModule::getExtInstSetId(llvm::StringRef setName) {

+ 34 - 0
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -1369,6 +1369,40 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
     stageVar->setIsSpirvBuiltin();
     return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleId);
   }
+  // According to DXIL spec, the StencilRef SV can only be used by PSOut.
+  case hlsl::Semantic::Kind::StencilRef: {
+    theBuilder.addExtension("SPV_EXT_shader_stencil_export");
+    theBuilder.requireCapability(spv::Capability::StencilExportEXT);
+
+    stageVar->setIsSpirvBuiltin();
+    return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragStencilRefEXT);
+  }
+  // According to DXIL spec, the RenderTargetArrayIndex SV can only be used by
+  // VSIn, VSOut, HSCPIn, HSCPOut, DSIn, DSOut, GSVIn, GSOut, PSIn.
+  // According to Vulkan spec, the Layer BuiltIn can only be used in GSOut and
+  // PSIn.
+  case hlsl::Semantic::Kind::RenderTargetArrayIndex: {
+    switch (sigPointKind) {
+    case hlsl::SigPoint::Kind::VSIn:
+    case hlsl::SigPoint::Kind::VSOut:
+    case hlsl::SigPoint::Kind::HSCPIn:
+    case hlsl::SigPoint::Kind::HSCPOut:
+    case hlsl::SigPoint::Kind::PCOut:
+    case hlsl::SigPoint::Kind::DSIn:
+    case hlsl::SigPoint::Kind::DSCPIn:
+    case hlsl::SigPoint::Kind::DSOut:
+    case hlsl::SigPoint::Kind::GSVIn:
+      return theBuilder.addStageIOVar(type, sc, name.str());
+    case hlsl::SigPoint::Kind::GSOut:
+    case hlsl::SigPoint::Kind::PSIn:
+      theBuilder.requireCapability(spv::Capability::Geometry);
+
+      stageVar->setIsSpirvBuiltin();
+      return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::Layer);
+    default:
+      llvm_unreachable("invalid usage of SV_RenderTargetArrayIndex sneaked in");
+    }
+  }
   default:
     emitError("semantic %0 unimplemented", srcLoc)
         << stageVar->getSemantic()->GetName();

+ 39 - 0
tools/clang/test/CodeGenSPIRV/semantic.render-target-array-index.ds.hlsl

@@ -0,0 +1,39 @@
+// Run: %dxc -T ds_6_0 -E main
+
+// HS PCF output
+struct HsPcfOut {
+  float  outTessFactor[4]   : SV_TessFactor;
+  float  inTessFactor[2]    : SV_InsideTessFactor;
+  uint   index              : SV_RenderTargetArrayIndex;
+};
+
+// Per-vertex input structs
+struct DsCpIn {
+  uint   index              : SV_RenderTargetArrayIndex;
+};
+
+// Per-vertex output structs
+struct DsCpOut {
+  uint   index              : SV_RenderTargetArrayIndex;
+};
+
+// CHECK:      OpEntryPoint TessellationEvaluation %main "main"
+// CHECK-SAME: %in_var_SV_RenderTargetArrayIndex
+// CHECK-SAME: %in_var_SV_RenderTargetArrayIndex_0
+// CHECK-SAME: %out_var_SV_RenderTargetArrayIndex
+
+
+// CHECK:      OpDecorate %in_var_SV_RenderTargetArrayIndex Location 0
+// CHECK:      OpDecorate %in_var_SV_RenderTargetArrayIndex_0 Location 1
+// CHECK:      OpDecorate %out_var_SV_RenderTargetArrayIndex Location 0
+
+// CHECK:      %in_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Input__arr_uint_uint_3 Input
+// CHECK:      %in_var_SV_RenderTargetArrayIndex_0 = OpVariable %_ptr_Input_uint Input
+// CHECK:      %out_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Output_uint Output
+
+[domain("quad")]
+DsCpOut main(OutputPatch<DsCpIn, 3> patch, HsPcfOut pcfData) {
+  DsCpOut dsOut;
+  dsOut = (DsCpOut)0;
+  return dsOut;
+}

+ 34 - 0
tools/clang/test/CodeGenSPIRV/semantic.render-target-array-index.gs.hlsl

@@ -0,0 +1,34 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK:      OpCapability Geometry
+
+// CHECK:      OpEntryPoint Geometry %main "main"
+// CHECK-SAME: %in_var_SV_RenderTargetArrayIndex
+// CHECK-SAME: %gl_Layer
+
+// CHECK:      OpDecorate %gl_Layer BuiltIn Layer
+// CHECK:      OpDecorate %in_var_SV_RenderTargetArrayIndex Location 0
+
+// CHECK:      %in_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Input__arr_uint_uint_2 Input
+// CHECK:      %gl_Layer = OpVariable %_ptr_Output_uint Output
+
+// GS per-vertex input
+struct GsVIn {
+  uint index : SV_RenderTargetArrayIndex;
+};
+
+// GS per-vertex output
+struct GsVOut {
+  uint index : SV_RenderTargetArrayIndex;
+};
+
+[maxvertexcount(2)]
+void main(in    line GsVIn              inData[2],
+          inout      LineStream<GsVOut> outData) {
+
+    GsVOut vertex;
+    vertex = (GsVOut)0;
+    outData.Append(vertex);
+
+    outData.RestartStrip();
+}

+ 49 - 0
tools/clang/test/CodeGenSPIRV/semantic.render-target-array-index.hs.hlsl

@@ -0,0 +1,49 @@
+// Run: %dxc -T hs_6_0 -E main
+
+#define NumOutPoints 2
+
+// CHECK:      OpEntryPoint TessellationControl %main "main"
+// CHECK-SAME: %in_var_SV_RenderTargetArrayIndex
+// CHECK-SAME: %out_var_SV_RenderTargetArrayIndex
+// CHECK-SAME: %out_var_SV_RenderTargetArrayIndex_0
+
+// CHECK:      OpDecorate %in_var_SV_RenderTargetArrayIndex Location 0
+// CHECK:      OpDecorate %out_var_SV_RenderTargetArrayIndex Location 0
+// CHECK:      OpDecorate %out_var_SV_RenderTargetArrayIndex_0 Location 1
+
+// CHECK:      %in_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Input__arr_uint_uint_2 Input
+// CHECK:      %out_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Output__arr_uint_uint_2 Output
+// CHECK:      %out_var_SV_RenderTargetArrayIndex_0 = OpVariable %_ptr_Output_uint Output
+
+struct HsCpIn {
+    uint index : SV_RenderTargetArrayIndex;
+};
+
+struct HsCpOut {
+    uint index : SV_RenderTargetArrayIndex;
+};
+
+struct HsPcfOut {
+  float tessOuter[4] : SV_TessFactor;
+  float tessInner[2] : SV_InsideTessFactor;
+  uint  index        : SV_RenderTargetArrayIndex;
+};
+
+// 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;
+}

+ 14 - 0
tools/clang/test/CodeGenSPIRV/semantic.render-target-array-index.ps.hlsl

@@ -0,0 +1,14 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK:      OpCapability Geometry
+
+// CHECK:      OpEntryPoint Fragment %main "main"
+// CHECK-SAME: %gl_Layer
+
+// CHECK:      OpDecorate %gl_Layer BuiltIn Layer
+
+// CHECK:      %gl_Layer = OpVariable %_ptr_Input_uint Input
+
+float4 main(uint input: SV_RenderTargetArrayIndex) : SV_Target {
+    return input;
+}

+ 15 - 0
tools/clang/test/CodeGenSPIRV/semantic.render-target-array-index.vs.hlsl

@@ -0,0 +1,15 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK:      OpEntryPoint Vertex %main "main"
+// CHECK-SAME: %in_var_SV_RenderTargetArrayIndex
+// CHECK-SMAE: %out_var_SV_RenderTargetArrayIndex
+
+// CHECK:      OpDecorate %in_var_SV_RenderTargetArrayIndex Location 0
+// CHECK:      OpDecorate %out_var_SV_RenderTargetArrayIndex Location 0
+
+// CHECK:      %in_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Input_uint Input
+// CHECK:      %out_var_SV_RenderTargetArrayIndex = OpVariable %_ptr_Output_uint Output
+
+uint main(uint input: SV_RenderTargetArrayIndex) : SV_RenderTargetArrayIndex {
+    return input;
+}

+ 15 - 0
tools/clang/test/CodeGenSPIRV/semantic.stencil-ref.ps.hlsl

@@ -0,0 +1,15 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK: OpCapability StencilExportEXT
+
+// CHECK: OpExtension "SPV_EXT_shader_stencil_export"
+
+// CHECK: OpEntryPoint Fragment %main "main" [[StencilRef:%\d+]]
+
+// CEHCK: OpDecorate [[StencilRef]] BuiltIn FragStencilRefEXT
+
+// CHECK: [[StencilRef]] = OpVariable %_ptr_Output_uint Output
+
+uint main() : SV_StencilRef {
+    return 3;
+}

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

@@ -459,6 +459,24 @@ TEST_F(FileTest, SemanticGSInstanceIDGS) {
 TEST_F(FileTest, SemanticSampleIndexPS) {
   runFileTest("semantic.sample-index.ps.hlsl");
 }
+TEST_F(FileTest, SemanticStencilRefPS) {
+  runFileTest("semantic.stencil-ref.ps.hlsl");
+}
+TEST_F(FileTest, SemanticRenderTargetArrayIndexVS) {
+  runFileTest("semantic.render-target-array-index.vs.hlsl");
+}
+TEST_F(FileTest, SemanticRenderTargetArrayIndexHS) {
+  runFileTest("semantic.render-target-array-index.hs.hlsl");
+}
+TEST_F(FileTest, SemanticRenderTargetArrayIndexDS) {
+  runFileTest("semantic.render-target-array-index.ds.hlsl");
+}
+TEST_F(FileTest, SemanticRenderTargetArrayIndexGS) {
+  runFileTest("semantic.render-target-array-index.gs.hlsl");
+}
+TEST_F(FileTest, SemanticRenderTargetArrayIndexPS) {
+  runFileTest("semantic.render-target-array-index.ps.hlsl");
+}
 
 // For texture methods
 TEST_F(FileTest, TextureSample) { runFileTest("texture.sample.hlsl"); }