Browse Source

[spirv] Emit Invocations execution mode in GS (#793)

OpExecutionMode Invocations n should be emitted for [instance(n)]
on GS. n defaults to 1.
Lei Zhang 7 years ago
parent
commit
e40535653f

+ 2 - 0
docs/SPIR-V.rst

@@ -2107,6 +2107,8 @@ and is translated to SPIR-V execution mode as follows:
 +=========================+=====================+==========================+
 |``maxvertexcount``       | ``n``               | ``OutputVertices n``     |
 +-------------------------+---------------------+--------------------------+
+|``instance``             | ``n``               | ``Invocations n``        |
++-------------------------+---------------------+--------------------------+
 
 Translation for Primitive Types
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ 7 - 0
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -5615,6 +5615,13 @@ bool SPIRVEmitter::processGeometryShaderAttributes(const FunctionDecl *decl,
                                 {static_cast<uint32_t>(vcAttr->getCount())});
   }
 
+  uint32_t invocations = 1;
+  if (auto *instanceAttr = decl->getAttr<HLSLInstanceAttr>()) {
+    invocations = static_cast<uint32_t>(instanceAttr->getCount());
+  }
+  theBuilder.addExecutionMode(entryFunctionId, spv::ExecutionMode::Invocations,
+                              {invocations});
+
   // Only one primitive type is permitted for the geometry shader.
   bool outPoint = false, outLine = false, outTriangle = false, inPoint = false,
        inLine = false, inTriangle = false, inLineAdj = false,

+ 7 - 0
tools/clang/test/CodeGenSPIRV/attribute.instance.gs.hlsl

@@ -0,0 +1,7 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK: OpExecutionMode %main Invocations 42
+
+[maxvertexcount(2)]
+[instance(42)]
+void main() {}

+ 6 - 0
tools/clang/test/CodeGenSPIRV/attribute.instance.missing.gs.hlsl

@@ -0,0 +1,6 @@
+// Run: %dxc -T gs_6_0 -E main
+
+// CHECK: OpExecutionMode %main Invocations 1
+
+[maxvertexcount(2)]
+void main() {}

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

@@ -741,6 +741,12 @@ TEST_F(FileTest, AttributeOutputControlPoints) {
 TEST_F(FileTest, AttributeMaxVertexCount) {
   runFileTest("attribute.max-vertex-count.hlsl");
 }
+TEST_F(FileTest, AttributeInstanceGS) {
+  runFileTest("attribute.instance.gs.hlsl");
+}
+TEST_F(FileTest, AttributeInstanceMissingGS) {
+  runFileTest("attribute.instance.missing.gs.hlsl");
+}
 
 // For geometry shader primitive types
 TEST_F(FileTest, PrimitivePointGS) { runFileTest("primitive.point.gs.hlsl"); }