瀏覽代碼

[spirv] Add support for DeviceIndex builtin. (#1171)

Ehsan 7 年之前
父節點
當前提交
c66c37cfa1

+ 2 - 0
docs/SPIR-V.rst

@@ -241,6 +241,8 @@ Right now the following ``<builtin>`` are supported:
   Need ``SPV_KHR_shader_draw_parameters`` extension.
 * ``DrawIndex``: The GLSL equivalent is ``gl_DrawIDARB``.
   Need ``SPV_KHR_shader_draw_parameters`` extension.
+* ``DeviceIndex``: The GLSL equivalent is ``gl_DeviceIndex``.
+  Need ``SPV_KHR_device_group`` extension.
 
 Please see Vulkan spec. `14.6. Built-In Variables <https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#interfaces-builtin-variables>`_
 for detailed explanation of these builtins.

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

@@ -1829,6 +1829,7 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
             .Case("BaseVertex", BuiltIn::BaseVertex)
             .Case("BaseInstance", BuiltIn::BaseInstance)
             .Case("DrawIndex", BuiltIn::DrawIndex)
+            .Case("DeviceIndex", BuiltIn::DeviceIndex)
             .Default(BuiltIn::Max);
 
     assert(spvBuiltIn != BuiltIn::Max); // The frontend should guarantee this.
@@ -1840,6 +1841,10 @@ uint32_t DeclResultIdMapper::createSpirvStageVar(StageVar *stageVar,
       theBuilder.addExtension("SPV_KHR_shader_draw_parameters");
       theBuilder.requireCapability(spv::Capability::DrawParameters);
       break;
+    case BuiltIn::DeviceIndex:
+      theBuilder.addExtension("SPV_KHR_device_group");
+      theBuilder.requireCapability(spv::Capability::DeviceGroup);
+      break;
     }
 
     return theBuilder.addStageBuiltinVar(type, sc, spvBuiltIn);
@@ -2242,6 +2247,18 @@ bool DeclResultIdMapper::validateVKBuiltins(const NamedDecl *decl,
             << builtin;
         success = false;
       }
+    } else if (builtin == "DeviceIndex") {
+      if (getStorageClassForSigPoint(sigPoint) != spv::StorageClass::Input) {
+        emitError("%0 builtin can only be used as shader input", loc)
+            << builtin;
+        success = false;
+      }
+      if (!declType->isSpecificBuiltinType(BuiltinType::Kind::Int) &&
+          !declType->isSpecificBuiltinType(BuiltinType::Kind::UInt)) {
+        emitError("%0 builtin must be of 32-bit scalar integer type", loc)
+            << builtin;
+        success = false;
+      }
     }
   }
 

+ 1 - 1
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -10472,7 +10472,7 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
   {
   case AttributeList::AT_VKBuiltIn:
     declAttr = ::new (S.Context) VKBuiltInAttr(A.getRange(), S.Context,
-      ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation,BaseVertex,BaseInstance,DrawIndex"),
+      ValidateAttributeStringArg(S, A, "PointSize,HelperInvocation,BaseVertex,BaseInstance,DrawIndex,DeviceIndex"),
       A.getAttributeSpellingListIndex());
     break;
   case AttributeList::AT_VKLocation:

+ 15 - 0
tools/clang/test/CodeGenSPIRV/spirv.builtin.device-index.hlsl

@@ -0,0 +1,15 @@
+// Run: %dxc -T vs_6_0 -E main
+
+// CHECK: OpCapability DeviceGroup
+
+// CHECK: OpExtension "SPV_KHR_device_group"
+
+
+// CHECK: OpDecorate [[a:%\d+]] BuiltIn DeviceIndex
+
+float main(
+  // CHECK: [[a]] = OpVariable %_ptr_Input_int Input
+  [[vk::builtin("DeviceIndex")]]    int deviceIndex : A
+) : OUTPUT{
+  return 1.0;
+}

+ 9 - 0
tools/clang/test/CodeGenSPIRV/spirv.builtin.device-index.invalid.hlsl

@@ -0,0 +1,9 @@
+// Run: %dxc -T ps_6_0 -E main
+
+[[vk::builtin("DeviceIndex")]]
+float4 main(float a : A) : SV_Target {
+    return a.xxxx;
+}
+
+// CHECK: :3:3: error: DeviceIndex builtin can only be used as shader input
+// CHECK: :3:3: error: DeviceIndex builtin must be of 32-bit scalar integer type

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

@@ -1142,6 +1142,12 @@ TEST_F(FileTest, SpirvBuiltInShaderDrawParametersInvalidUsage) {
   runFileTest("spirv.builtin.shader-draw-parameters.invalid.hlsl",
               Expect::Failure);
 }
+TEST_F(FileTest, SpirvBuiltInDeviceIndex) {
+  runFileTest("spirv.builtin.device-index.hlsl");
+}
+TEST_F(FileTest, SpirvBuiltInDeviceIndexInvalidUsage) {
+  runFileTest("spirv.builtin.device-index.invalid.hlsl", Expect::Failure);
+}
 
 // For shader stage input/output interface
 // For semantic SV_Position, SV_ClipDistance, SV_CullDistance