Browse Source

[spirv] Add support for SV_Coverage (#800)

Also emit an error for SV_InnerCoverage.
Lei Zhang 7 years ago
parent
commit
83e23e6954

+ 113 - 111
docs/SPIR-V.rst

@@ -753,117 +753,119 @@ 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
 .. 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                   |
-+---------------------------+-------------+--------------------------+-----------------------+
-| SV_StencilRef             | PSOut       | ``FragStencilRefEXT``    | N/A                   |
-+---------------------------+-------------+--------------------------+-----------------------+
-|                           | GSOut       | ``Layer``                | N/A                   |
-| SV_RenderTargetArrayIndex +-------------+--------------------------+-----------------------+
-|                           | PSIn        | ``Layer``                | N/A                   |
-+---------------------------+-------------+--------------------------+-----------------------+
-|                           | GSOut       | ``ViewportIndex``        | N/A                   |
-| SV_ViewportArrayIndex     +-------------+--------------------------+-----------------------+
-|                           | PSIn        | ``ViewportIndex``        | N/A                   |
-+---------------------------+-------------+--------------------------+-----------------------+
-
-[TODO] add other SV semantic strings in the above
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| HLSL Semantic             | SigPoint    | SPIR-V ``BuiltIn``       | SPIR-V Execution Mode |   SPIR-V Capability   |
++===========================+=============+==========================+=======================+=======================+
+|                           | VSOut       | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPIn      | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPOut     | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSCPIn      | ``Position``             | N/A                   | ``Shader``            |
+| SV_Position               +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSOut       | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSVIn       | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``Position``             | N/A                   | ``Shader``            |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``FragCoord``            | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | VSOut       | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPIn      | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPOut     | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSCPIn      | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+| SV_ClipDistance           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSOut       | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSVIn       | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``ClipDistance``         | N/A                   | ``ClipDistance``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | VSOut       | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPIn      | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSCPOut     | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSCPIn      | ``CullDistance``         | N/A                   | ``CullDistance``      |
+| SV_CullDistance           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSOut       | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSVIn       | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``CullDistance``         | N/A                   | ``CullDistance``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``CullDistance``         | N/A                   | ``CullDistance``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_VertexID               | VSIn        | ``VertexIndex``          | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_InstanceID             | VSIn        | ``InstanceIndex``        | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_Depth                  | PSOut       | ``FragDepth``            | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_DepthGreaterEqual      | PSOut       | ``FragDepth``            | ``DepthGreater``      | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_DepthLessEqual         | PSOut       | ``FragDepth``            | ``DepthLess``         | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_IsFrontFace            | PSIn        | ``FrontFacing``          | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_DispatchThreadID       | CSIn        | ``GlobalInvocationId``   | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_GroupID                | CSIn        | ``WorkgroupId``          | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_GroupThreadID          | CSIn        | ``LocalInvocationId``    | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_GroupIndex             | CSIn        | ``LocalInvocationIndex`` | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_OutputControlPointID   | HSIn        | ``InvocationId``         | N/A                   | ``Tessellation``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_GSInstanceID           | GSIn        | ``InvocationId``         | N/A                   | ``Geometry``          |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_DomainLocation         | DSIn        | ``TessCoord``            | N/A                   | ``Tessellation``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | HSIn        | ``PrimitiveId``          | N/A                   | ``Tessellation``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PCIn        | ``PrimitiveId``          | N/A                   | ``Tessellation``      |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DsIn        | ``PrimitiveId``          | N/A                   | ``Tessellation``      |
+| SV_PrimitiveID            +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSIn        | ``PrimitiveId``          | N/A                   | ``Geometry``          |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``PrimitiveId``          | N/A                   | ``Geometry``          |
+|                           +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``PrimitiveId``          | N/A                   | ``Geometry``          |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | PCOut       | ``TessLevelOuter``       | N/A                   | ``Tessellation``      |
+| SV_TessFactor             +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSIn        | ``TessLevelOuter``       | N/A                   | ``Tessellation``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | PCOut       | ``TessLevelInner``       | N/A                   | ``Tessellation``      |
+| SV_InsideTessFactor       +-------------+--------------------------+-----------------------+-----------------------+
+|                           | DSIn        | ``TessLevelInner``       | N/A                   | ``Tessellation``      |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_SampleIndex            | PSIn        | ``SampleId``             | N/A                   | ``SampleRateShading`` |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+| SV_StencilRef             | PSOut       | ``FragStencilRefEXT``    | N/A                   | ``StencilExportEXT``  |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``Layer``                | N/A                   | ``Geometry``          |
+| SV_RenderTargetArrayIndex +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``Layer``                | N/A                   | ``Geometry``          |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | GSOut       | ``ViewportIndex``        | N/A                   | ``MultiViewport``     |
+| SV_ViewportArrayIndex     +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``ViewportIndex``        | N/A                   | ``MultiViewport``     |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSIn        | ``SampleMask``           | N/A                   | ``Shader``            |
+| SV_Coverage               +-------------+--------------------------+-----------------------+-----------------------+
+|                           | PSOut       | ``SampleMask``           | N/A                   | ``Shader``            |
++---------------------------+-------------+--------------------------+-----------------------+-----------------------+
 
 
 For entities (function parameters, function return values, struct fields) with
 For entities (function parameters, function return values, struct fields) with
 the above SV semantic strings attached, SPIR-V variables of the
 the above SV semantic strings attached, SPIR-V variables of the

+ 55 - 13
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -26,10 +26,11 @@ namespace spirv {
 
 
 namespace {
 namespace {
 /// \brief Returns true if the given decl has a semantic string attached and
 /// \brief Returns true if the given decl has a semantic string attached and
-/// writes the info to *semanticStr, *semantic, and *semanticIndex.
+/// writes the info to *semanticStr, *semantic, *semanticIndex, and
+/// *semanticLoc.
 bool getStageVarSemantic(const NamedDecl *decl, llvm::StringRef *semanticStr,
 bool getStageVarSemantic(const NamedDecl *decl, llvm::StringRef *semanticStr,
                          const hlsl::Semantic **semantic,
                          const hlsl::Semantic **semantic,
-                         uint32_t *semanticIndex) {
+                         uint32_t *semanticIndex, SourceLocation *semanticLoc) {
   for (auto *annotation : decl->getUnusualAnnotations()) {
   for (auto *annotation : decl->getUnusualAnnotations()) {
     if (auto *sema = dyn_cast<hlsl::SemanticDecl>(annotation)) {
     if (auto *sema = dyn_cast<hlsl::SemanticDecl>(annotation)) {
       *semanticStr = sema->SemanticName;
       *semanticStr = sema->SemanticName;
@@ -37,6 +38,7 @@ bool getStageVarSemantic(const NamedDecl *decl, llvm::StringRef *semanticStr,
       hlsl::Semantic::DecomposeNameAndIndex(*semanticStr, &semanticName,
       hlsl::Semantic::DecomposeNameAndIndex(*semanticStr, &semanticName,
                                             semanticIndex);
                                             semanticIndex);
       *semantic = hlsl::Semantic::GetByName(semanticName);
       *semantic = hlsl::Semantic::GetByName(semanticName);
+      *semanticLoc = sema->Loc;
       return true;
       return true;
     }
     }
   }
   }
@@ -823,8 +825,10 @@ bool DeclResultIdMapper::createStageVars(
   llvm::StringRef semanticStr;
   llvm::StringRef semanticStr;
   const hlsl::Semantic *semantic = {};
   const hlsl::Semantic *semantic = {};
   uint32_t semanticIndex = {};
   uint32_t semanticIndex = {};
+  SourceLocation semanticLoc = {};
 
 
-  if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex)) {
+  if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
+                          &semanticLoc)) {
     const auto semanticKind = semantic->GetKind();
     const auto semanticKind = semantic->GetKind();
 
 
     // Found semantic attached directly to this Decl. This means we need to
     // Found semantic attached directly to this Decl. This means we need to
@@ -841,8 +845,8 @@ bool DeclResultIdMapper::createStageVars(
       return false;
       return false;
     }
     }
 
 
-    // Special handling of certain mapping between HLSL semantics and
-    // SPIR-V builtin:
+    // Special handling of certain mappings between HLSL semantics and
+    // SPIR-V builtins:
     // * SV_Position/SV_CullDistance/SV_ClipDistance should be grouped into the
     // * SV_Position/SV_CullDistance/SV_ClipDistance should be grouped into the
     //   gl_PerVertex struct in vertex processing stages.
     //   gl_PerVertex struct in vertex processing stages.
     // * SV_DomainLocation can refer to a float2, whereas TessCoord is a float3.
     // * SV_DomainLocation can refer to a float2, whereas TessCoord is a float3.
@@ -854,30 +858,42 @@ bool DeclResultIdMapper::createStageVars(
     // * SV_InsideTessFactor is a single float for tri patch, and an array of
     // * SV_InsideTessFactor is a single float for tri patch, and an array of
     //   size 2 for a quad patch, but it must always be an array of size 2 in
     //   size 2 for a quad patch, but it must always be an array of size 2 in
     //   SPIR-V for Vulkan.
     //   SPIR-V for Vulkan.
+    // * SV_Coverage is an uint value, but the builtin it corresponds to,
+    //   SampleMask, must be an array of integers.
+
     if (glPerVertex.tryToAccess(sigPoint->GetKind(), semanticKind,
     if (glPerVertex.tryToAccess(sigPoint->GetKind(), semanticKind,
                                 semanticIndex, invocationId, value,
                                 semanticIndex, invocationId, value,
                                 noWriteBack))
                                 noWriteBack))
       return true;
       return true;
 
 
-    if (semanticKind == hlsl::Semantic::Kind::DomainLocation)
+    const uint32_t srcTypeId = typeId; // Variable type in source code
+
+    switch (semanticKind) {
+    case hlsl::Semantic::Kind::DomainLocation:
       typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 3);
       typeId = theBuilder.getVecType(theBuilder.getFloat32Type(), 3);
-    else if (semanticKind == hlsl::Semantic::Kind::TessFactor)
+      break;
+    case hlsl::Semantic::Kind::TessFactor:
       typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
       typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
                                        theBuilder.getConstantUint32(4));
                                        theBuilder.getConstantUint32(4));
-    else if (semanticKind == hlsl::Semantic::Kind::InsideTessFactor)
+      break;
+    case hlsl::Semantic::Kind::InsideTessFactor:
       typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
       typeId = theBuilder.getArrayType(theBuilder.getFloat32Type(),
                                        theBuilder.getConstantUint32(2));
                                        theBuilder.getConstantUint32(2));
+      break;
+    case hlsl::Semantic::Kind::Coverage:
+      typeId = theBuilder.getArrayType(typeId, theBuilder.getConstantUint32(1));
+      break;
+    }
 
 
     // Handle the extra arrayness
     // Handle the extra arrayness
-    const uint32_t elementTypeId = typeId;
+    const uint32_t elementTypeId = typeId; // Array element's type
     if (arraySize != 0)
     if (arraySize != 0)
       typeId = theBuilder.getArrayType(typeId,
       typeId = theBuilder.getArrayType(typeId,
                                        theBuilder.getConstantUint32(arraySize));
                                        theBuilder.getConstantUint32(arraySize));
 
 
     StageVar stageVar(sigPoint, semanticStr, semantic, semanticIndex, typeId);
     StageVar stageVar(sigPoint, semanticStr, semantic, semanticIndex, typeId);
     llvm::Twine name = namePrefix + "." + semanticStr;
     llvm::Twine name = namePrefix + "." + semanticStr;
-    const uint32_t varId =
-        createSpirvStageVar(&stageVar, name, decl->getLocation());
+    const uint32_t varId = createSpirvStageVar(&stageVar, name, semanticLoc);
 
 
     if (varId == 0)
     if (varId == 0)
       return false;
       return false;
@@ -938,6 +954,11 @@ bool DeclResultIdMapper::createStageVars(
             theBuilder.getVecType(theBuilder.getFloat32Type(), domainLocSize),
             theBuilder.getVecType(theBuilder.getFloat32Type(), domainLocSize),
             *value, *value, {0, 1});
             *value, *value, {0, 1});
       }
       }
+      // Special handling of SV_Coverage, which is an uint value. We need to
+      // read SampleMask and extract its first element.
+      else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
+        *value = theBuilder.createCompositeExtract(srcTypeId, *value, {0});
+      }
     } else {
     } else {
       if (noWriteBack)
       if (noWriteBack)
         return true;
         return true;
@@ -974,6 +995,14 @@ bool DeclResultIdMapper::createStageVars(
             varId, theBuilder.getConstantUint32(0));
             varId, theBuilder.getConstantUint32(0));
         theBuilder.createStore(ptr, *value);
         theBuilder.createStore(ptr, *value);
       }
       }
+      // Special handling of SV_Coverage, which is an unit value. We need to
+      // write it to the first element in the SampleMask builtin.
+      else if (semanticKind == hlsl::Semantic::Kind::Coverage) {
+        ptr = theBuilder.createAccessChain(
+            theBuilder.getPointerType(srcTypeId, spv::StorageClass::Output),
+            varId, theBuilder.getConstantUint32(0));
+        theBuilder.createStore(ptr, *value);
+      }
       // Special handling of HS ouput, for which we write to only one
       // Special handling of HS ouput, for which we write to only one
       // element in the per-vertex data array: the one indexed by
       // element in the per-vertex data array: the one indexed by
       // SV_ControlPointID.
       // SV_ControlPointID.
@@ -1096,8 +1125,10 @@ bool DeclResultIdMapper::writeBackOutputStream(const ValueDecl *decl,
   llvm::StringRef semanticStr;
   llvm::StringRef semanticStr;
   const hlsl::Semantic *semantic = {};
   const hlsl::Semantic *semantic = {};
   uint32_t semanticIndex = {};
   uint32_t semanticIndex = {};
+  SourceLocation semanticLoc = {};
 
 
-  if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex)) {
+  if (getStageVarSemantic(decl, &semanticStr, &semantic, &semanticIndex,
+                          &semanticLoc)) {
     // Found semantic attached directly to this Decl. Write the value for this
     // Found semantic attached directly to this Decl. Write the value for this
     // Decl to the corresponding stage output variable.
     // Decl to the corresponding stage output variable.
 
 
@@ -1357,7 +1388,7 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
     // PrimitiveId requires either Tessellation or Geometry capability.
     // PrimitiveId requires either Tessellation or Geometry capability.
     // Need to require one for PSIn.
     // Need to require one for PSIn.
     if (sigPointKind == hlsl::SigPoint::Kind::PSIn)
     if (sigPointKind == hlsl::SigPoint::Kind::PSIn)
-      theBuilder.requireCapability(spv::Capability::Tessellation);
+      theBuilder.requireCapability(spv::Capability::Geometry);
 
 
     // Translate to PrimitiveId BuiltIn for all valid SigPoints.
     // Translate to PrimitiveId BuiltIn for all valid SigPoints.
     stageVar->setIsSpirvBuiltin();
     stageVar->setIsSpirvBuiltin();
@@ -1460,6 +1491,17 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
       llvm_unreachable("invalid usage of SV_ViewportArrayIndex sneaked in");
       llvm_unreachable("invalid usage of SV_ViewportArrayIndex sneaked in");
     }
     }
   }
   }
+  // According to DXIL spec, the Coverage SV can only be used by PSIn and PSOut.
+  // According to Vulkan spec, the SampleMask BuiltIn can only be used in
+  // PSIn and PSOut.
+  case hlsl::Semantic::Kind::Coverage: {
+    stageVar->setIsSpirvBuiltin();
+    return theBuilder.addStageBuiltinVar(type, sc, BuiltIn::SampleMask);
+  }
+  case hlsl::Semantic::Kind::InnerCoverage: {
+    emitError("no equivalent for semantic SV_InnerCoverage in Vulkan", srcLoc);
+    return 0;
+  }
   default:
   default:
     emitError("semantic %0 unimplemented", srcLoc)
     emitError("semantic %0 unimplemented", srcLoc)
         << stageVar->getSemantic()->GetName();
         << stageVar->getSemantic()->GetName();

+ 13 - 0
tools/clang/test/CodeGenSPIRV/semantic.coverage.ps.hlsl

@@ -0,0 +1,13 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK: OpEntryPoint Fragment %main "main" %gl_SampleMask %gl_SampleMask_0
+
+// CHECK: OpDecorate %gl_SampleMask BuiltIn SampleMask
+// CHECK: OpDecorate %gl_SampleMask_0 BuiltIn SampleMask
+
+// CHECK: %gl_SampleMask = OpVariable %_ptr_Input__arr_uint_uint_1 Input
+// CHECK: %gl_SampleMask_0 = OpVariable %_ptr_Output__arr_uint_uint_1 Output
+
+uint main(uint inCov : SV_Coverage) : SV_Coverage {
+    return inCov;
+}

+ 19 - 0
tools/clang/test/CodeGenSPIRV/semantic.coverage.type-mismatch.ps.hlsl

@@ -0,0 +1,19 @@
+// Run: %dxc -T ps_6_0 -E main
+
+// CHECK:                         OpDecorate %gl_SampleMask BuiltIn SampleMask
+// CHECK:                         OpDecorate %gl_SampleMask_0 BuiltIn SampleMask
+
+// CHECK:        %gl_SampleMask = OpVariable %_ptr_Input__arr_uint_uint_1 Input
+// CHECK:      %gl_SampleMask_0 = OpVariable %_ptr_Output__arr_uint_uint_1 Output
+
+// CHECK:      %param_var_inCov = OpVariable %_ptr_Function_uint Function
+// CHECK-NEXT:     [[val:%\d+]] = OpLoad %_arr_uint_uint_1 %gl_SampleMask
+// CHECK-NEXT: [[element:%\d+]] = OpCompositeExtract %uint [[val]] 0
+// CHECK-NEXT:                    OpStore %param_var_inCov [[element]]
+// CHECK-NEXT:     [[ret:%\d+]] = OpFunctionCall %uint %src_main %param_var_inCov
+// CHECK-NEXT:     [[ptr:%\d+]] = OpAccessChain %_ptr_Output_uint %gl_SampleMask_0 %uint_0
+// CHECK-NEXT:                    OpStore [[ptr]] [[ret]]
+
+uint main(uint inCov : SV_Coverage) : SV_Coverage {
+    return inCov;
+}

+ 7 - 0
tools/clang/test/CodeGenSPIRV/semantic.inner-coverage.ps.hlsl

@@ -0,0 +1,7 @@
+// Run: %dxc -T ps_6_0 -E main
+
+float4 main(uint inCov : SV_InnerCoverage) : SV_Target {
+    return 1.0;
+}
+
+// CHECK: 3:26: error: no equivalent for semantic SV_InnerCoverage in Vulkan

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

@@ -1,6 +1,6 @@
 // Run: %dxc -T ps_6_0 -E main
 // Run: %dxc -T ps_6_0 -E main
 
 
-// CHECK: OpCapability Tessellation
+// CHECK: OpCapability Geometry
 
 
 // CHECK:      OpEntryPoint Fragment %main "main"
 // CHECK:      OpEntryPoint Fragment %main "main"
 // CHECK-SAME: %gl_PrimitiveID
 // CHECK-SAME: %gl_PrimitiveID

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

@@ -492,6 +492,15 @@ TEST_F(FileTest, SemanticViewportArrayIndexGS) {
 TEST_F(FileTest, SemanticViewportArrayIndexPS) {
 TEST_F(FileTest, SemanticViewportArrayIndexPS) {
   runFileTest("semantic.viewport-array-index.ps.hlsl");
   runFileTest("semantic.viewport-array-index.ps.hlsl");
 }
 }
+TEST_F(FileTest, SemanticCoveragePS) {
+  runFileTest("semantic.coverage.ps.hlsl");
+}
+TEST_F(FileTest, SemanticCoverageTypeMismatchPS) {
+  runFileTest("semantic.coverage.type-mismatch.ps.hlsl");
+}
+TEST_F(FileTest, SemanticInnerCoveragePS) {
+  runFileTest("semantic.inner-coverage.ps.hlsl", Expect::Failure);
+}
 
 
 // For texture methods
 // For texture methods
 TEST_F(FileTest, TextureSample) { runFileTest("texture.sample.hlsl"); }
 TEST_F(FileTest, TextureSample) { runFileTest("texture.sample.hlsl"); }