瀏覽代碼

[spirv] Error out if numthreads is not provided for CS. (#2820)

* [spirv] Error out if numthreads is not provided for CS.

* [spirv] Add tests for lib shaders.
Ehsan 5 年之前
父節點
當前提交
6d4195fd4d
共有 43 個文件被更改,包括 81 次插入7 次删除
  1. 5 0
      tools/clang/lib/SPIRV/SpirvEmitter.cpp
  2. 16 0
      tools/clang/test/CodeGenSPIRV/attribute.numthreads.lib.hlsl
  3. 14 0
      tools/clang/test/CodeGenSPIRV/attribute.numthreads.lib.missing.hlsl
  4. 1 3
      tools/clang/test/CodeGenSPIRV/attribute.numthreads.missing.hlsl
  5. 1 0
      tools/clang/test/CodeGenSPIRV/cs.groupshared.function-param.hlsl
  6. 1 0
      tools/clang/test/CodeGenSPIRV/cs.groupshared.function-param.out.hlsl
  7. 1 0
      tools/clang/test/CodeGenSPIRV/cs.groupshared.struct-function.hlsl
  8. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.allmemorybarrier.hlsl
  9. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.allmemorybarrierwithgroupsync.hlsl
  10. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.devicememorybarrier.hlsl
  11. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.devicememorybarrierwithgroupsync.hlsl
  12. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.groupmemorybarrier.hlsl
  13. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.groupmemorybarrierwithgroupsync.hlsl
  14. 1 0
      tools/clang/test/CodeGenSPIRV/intrinsics.interlocked-methods.cs.hlsl
  15. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/01-copy-global-static-ok.hlsl
  16. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/02-write-global-static-ok.hlsl
  17. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/03-copy-local-struct-ok.hlsl
  18. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/04-copy-local-nested-struct-ok.hlsl
  19. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/05-func-param-sbuf-ok.hlsl
  20. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/06-func-param-rwsbuf-ok.hlsl
  21. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/07-func-ret-tmp-var-ok.hlsl
  22. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/08-func-ret-direct-ok.hlsl
  23. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/09-if-stmt-select-fail.hlsl
  24. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/10-if-stmt-select-ok.hlsl
  25. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/11-if-stmt-const-ok.hlsl
  26. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/12-switch-stmt-select-fail.hlsl
  27. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/13-switch-stmt-const-ok.hlsl
  28. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/14-loop-var-fail.hlsl
  29. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/15-loop-var-unroll-ok.hlsl
  30. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/16-loop-var-range-fail.hlsl
  31. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/17-loop-var-float-fail.hlsl
  32. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/18-multi-func-call-ok.hlsl
  33. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/19-multi-func-ret-fail.hlsl
  34. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/20-multi-func-ret-const-ok.hlsl
  35. 1 0
      tools/clang/test/CodeGenSPIRV/legal-examples/21-combined-ok.hlsl
  36. 1 0
      tools/clang/test/CodeGenSPIRV/semantic.group-index.cs.hlsl
  37. 1 1
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.control.barrier.hlsl
  38. 1 1
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.vulkan1.1.hlsl
  39. 1 1
      tools/clang/test/CodeGenSPIRV/spirv.debug.opline.precedence.hlsl
  40. 1 0
      tools/clang/test/CodeGenSPIRV/type.append.consume-structured-buffer.cast.hlsl
  41. 1 0
      tools/clang/test/CodeGenSPIRV/type.rwbuffer.half.hlsl
  42. 1 0
      tools/clang/test/CodeGenSPIRV/var.init.vec.size.1.hlsl
  43. 7 1
      tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

+ 5 - 0
tools/clang/lib/SPIRV/SpirvEmitter.cpp

@@ -10253,6 +10253,11 @@ void SpirvEmitter::processComputeShaderAttributes(const FunctionDecl *decl) {
     x = static_cast<uint32_t>(numThreadsAttr->getX());
     y = static_cast<uint32_t>(numThreadsAttr->getY());
     z = static_cast<uint32_t>(numThreadsAttr->getZ());
+  } else {
+    emitError("thread group size [numthreads(x,y,z)] is missing from the "
+              "entry-point function",
+              decl->getLocation());
+    return;
   }
 
   spvBuilder.addExecutionMode(entryFunction, spv::ExecutionMode::LocalSize,

+ 16 - 0
tools/clang/test/CodeGenSPIRV/attribute.numthreads.lib.hlsl

@@ -0,0 +1,16 @@
+// Run: %dxc -T lib_6_4 -E main
+
+// CHECK: OpExecutionMode %entryHistogram LocalSize 16 16 1
+[shader("compute")]
+[numthreads(16, 16, 1)]
+void entryHistogram(uint3 id: SV_DispatchThreadID, uint idx: SV_GroupIndex)
+{
+}
+
+// CHECK: OpExecutionMode %entryAverage LocalSize 256 1 1
+[shader("compute")]
+[numthreads(256, 1, 1)]
+void entryAverage(uint3 id: SV_DispatchThreadID, uint idx: SV_GroupIndex)
+{
+}
+

+ 14 - 0
tools/clang/test/CodeGenSPIRV/attribute.numthreads.lib.missing.hlsl

@@ -0,0 +1,14 @@
+// Run: %dxc -T lib_6_4 -E main
+
+[shader("compute")]
+[numthreads(16, 16, 1)]
+void entryHistogram(uint3 id: SV_DispatchThreadID, uint idx: SV_GroupIndex)
+{
+}
+
+// CHECK: 11:6: error: thread group size [numthreads(x,y,z)] is missing from the entry-point function
+[shader("compute")]
+void entryAverage(uint3 id: SV_DispatchThreadID, uint idx: SV_GroupIndex)
+{
+}
+

+ 1 - 3
tools/clang/test/CodeGenSPIRV/attribute.numthreads.missing.hlsl

@@ -1,6 +1,4 @@
 // Run: %dxc -T cs_6_0 -E main
 
-// CHECK: OpEntryPoint GLCompute %main "main"
-// CHECK: OpExecutionMode %main LocalSize 1 1 1
-
+// CHECK: 4:6: error: thread group size [numthreads(x,y,z)] is missing from the entry-point function
 void main() {}

+ 1 - 0
tools/clang/test/CodeGenSPIRV/cs.groupshared.function-param.hlsl

@@ -16,6 +16,7 @@ int foo(int x, int y, int z, int w[10], int v) {
   return x | y | z | w[0] | v;
 }
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: %E = OpVariable %_ptr_Function_int Function
   int E;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/cs.groupshared.function-param.out.hlsl

@@ -25,6 +25,7 @@ groupshared int C;
 // CHECK: %D = OpVariable %_ptr_Workgroup_S Workgroup
 groupshared S D;
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: %E = OpVariable %_ptr_Function_int Function
   int E;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/cs.groupshared.struct-function.hlsl

@@ -25,6 +25,7 @@ groupshared S C;
 // CHECK: %D = OpVariable %_ptr_Workgroup_S Workgroup
 groupshared S D;
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: %E = OpVariable %_ptr_Function_S Function
   S E;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.allmemorybarrier.hlsl

@@ -3,6 +3,7 @@
 // Memory scope : Device = 0x1 = 1
 // Semantics: ImageMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x40 | 0x100 | 0x8 = 2376
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpMemoryBarrier %uint_1 %uint_2376
   AllMemoryBarrier();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.allmemorybarrierwithgroupsync.hlsl

@@ -4,6 +4,7 @@
 // Memory scope : Device = 0x1 = 1
 // Semantics: ImageMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x40 | 0x100 | 0x8 = 2376
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpControlBarrier %uint_2 %uint_1 %uint_2376
   AllMemoryBarrierWithGroupSync();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.devicememorybarrier.hlsl

@@ -3,6 +3,7 @@
 // Memory scope : Device = 0x1 = 1
 // Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpMemoryBarrier %uint_1 %uint_2120
   DeviceMemoryBarrier();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.devicememorybarrierwithgroupsync.hlsl

@@ -4,6 +4,7 @@
 // Memory scope : Device = 0x1 = 1
 // Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpControlBarrier %uint_2 %uint_1 %uint_2120
   DeviceMemoryBarrierWithGroupSync();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.groupmemorybarrier.hlsl

@@ -3,6 +3,7 @@
 // Memory scope : Workgroup = 0x2 = 2
 // Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpMemoryBarrier %uint_2 %uint_264
   GroupMemoryBarrier();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.groupmemorybarrierwithgroupsync.hlsl

@@ -4,6 +4,7 @@
 // Memory scope : Workgroup = 0x2 = 2
 // Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK: OpControlBarrier %uint_2 %uint_2 %uint_264
   GroupMemoryBarrierWithGroupSync();

+ 1 - 0
tools/clang/test/CodeGenSPIRV/intrinsics.interlocked-methods.cs.hlsl

@@ -8,6 +8,7 @@ RWBuffer<uint> getDest() {
   return buff;
 }
 
+[numthreads(1,1,1)]
 void main()
 {
   uint original_u_val;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/01-copy-global-static-ok.hlsl

@@ -16,6 +16,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 static StructuredBuffer<S> sSBuffer = gSBuffer;
 
+[numthreads(1,1,1)]
 void main() {
   gRWSBuffer[i] = sSBuffer[i];
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/02-write-global-static-ok.hlsl

@@ -14,6 +14,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 static RWStructuredBuffer<S> sRWSBuffer = gRWSBuffer;
 
+[numthreads(1,1,1)]
 void main() {
   sRWSBuffer[i].f = 0.0;
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/03-copy-local-struct-ok.hlsl

@@ -20,6 +20,7 @@ int i;
 StructuredBuffer<S> gSBuffer;
 RWStructuredBuffer<S> gRWSBuffer;
 
+[numthreads(1,1,1)]
 void main() {
   CombinedBuffers cb;
   cb.SBuffer = gSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/04-copy-local-nested-struct-ok.hlsl

@@ -27,6 +27,7 @@ int i;
 StructuredBuffer<S> gSBuffer;
 RWStructuredBuffer<S> gRWSBuffer;
 
+[numthreads(1,1,1)]
 void main() {
   S1 s1;
   s1.s2.cb.SBuffer = gSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/05-func-param-sbuf-ok.hlsl

@@ -24,6 +24,7 @@ void foo(StructuredBuffer<S> pSBuffer) {
   gRWSBuffer[i] = pSBuffer[i];
 }
 
+[numthreads(1,1,1)]
 void main() {
   foo(gSBuffer);
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/06-func-param-rwsbuf-ok.hlsl

@@ -18,6 +18,7 @@ void foo(RWStructuredBuffer<S> pRWSBuffer) {
   pRWSBuffer[i] = gSBuffer[i];
 }
 
+[numthreads(1,1,1)]
 void main() {
   foo(gRWSBuffer);
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/07-func-ret-tmp-var-ok.hlsl

@@ -18,6 +18,7 @@ RWStructuredBuffer<S> foo() {
   return gRWSBuffer;
 }
 
+[numthreads(1,1,1)]
 void main() {
   RWStructuredBuffer<S> lRWSBuffer = foo();
   lRWSBuffer[i] = gSBuffer[i];

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/08-func-ret-direct-ok.hlsl

@@ -18,6 +18,7 @@ StructuredBuffer<S> foo() {
   return gSBuffer;
 }
 
+[numthreads(1,1,1)]
 void main() {
   gRWSBuffer[i] = foo()[i];
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/09-if-stmt-select-fail.hlsl

@@ -20,6 +20,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
   StructuredBuffer<S> lSBuffer;
   if (constant > i) {          // Condition can't be computed at compile time.

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/10-if-stmt-select-ok.hlsl

@@ -28,6 +28,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/11-if-stmt-const-ok.hlsl

@@ -17,6 +17,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/12-switch-stmt-select-fail.hlsl

@@ -20,6 +20,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/13-switch-stmt-const-ok.hlsl

@@ -23,6 +23,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 const static int constant = 0;
 
+[numthreads(1,1,1)]
 void main() {
   StructuredBuffer<S> lSBuffer;
   switch(constant) {

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/14-loop-var-fail.hlsl

@@ -17,6 +17,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/15-loop-var-unroll-ok.hlsl

@@ -25,6 +25,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/16-loop-var-range-fail.hlsl

@@ -62,6 +62,7 @@ void foo3() {
 }
 
 
+[numthreads(1,1,1)]
 void main() {
   foo1(); foo2(); foo3();
 }

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/17-loop-var-float-fail.hlsl

@@ -17,6 +17,7 @@ RWStructuredBuffer<S> gRWSBuffer;
 
 #define constant 0
 
+[numthreads(1,1,1)]
 void main() {
 
   StructuredBuffer<S> lSBuffer;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/18-multi-func-call-ok.hlsl

@@ -23,6 +23,7 @@ void foo(RWStructuredBuffer<S> pRWSBuffer) {
   pRWSBuffer[i] = gSBuffer[i];
 }
 
+[numthreads(1,1,1)]
 void main() {
   foo(gRWSBuffer1);
   foo(gRWSBuffer2);

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/19-multi-func-ret-fail.hlsl

@@ -21,6 +21,7 @@ RWStructuredBuffer<S> foo(int l) {
   }
 }
 
+[numthreads(1,1,1)]
 void main() {
   RWStructuredBuffer<S> lRWSBuffer = foo(i);
   lRWSBuffer[i] = gSBuffer[i];

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/20-multi-func-ret-const-ok.hlsl

@@ -28,6 +28,7 @@ StructuredBuffer<S> foo(int l) {
   }
 }
 
+[numthreads(1,1,1)]
 void main() {
   gRWSBuffer1[i] = foo(0)[i];
   gRWSBuffer2[i] = foo(1)[i];

+ 1 - 0
tools/clang/test/CodeGenSPIRV/legal-examples/21-combined-ok.hlsl

@@ -34,6 +34,7 @@ void foo(RWStructuredBuffer<S> pRWSBuffer) {
   pRWSBuffer[i] = lSBuffer[i];
 }
 
+[numthreads(1,1,1)]
 void main() {
   foo(gRWSBuffer1);
   foo(gRWSBuffer2);

+ 1 - 0
tools/clang/test/CodeGenSPIRV/semantic.group-index.cs.hlsl

@@ -4,4 +4,5 @@
 // CHECK: OpDecorate %gl_LocalInvocationIndex BuiltIn LocalInvocationIndex
 // CHECK: %gl_LocalInvocationIndex = OpVariable %_ptr_Input_uint Input
 
+[numthreads(1,1,1)]
 void main(uint gid : SV_GroupIndex) : A {}

+ 1 - 1
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.control.barrier.hlsl

@@ -5,7 +5,7 @@
 
 groupshared int dest_i;
 
-void main() {
+[numthreads(1,1,1)]void main() {
 // CHECK:      OpLine [[file]] 11 3
 // CHECK-NEXT: OpControlBarrier %uint_2 %uint_1 %uint_2376
   AllMemoryBarrierWithGroupSync();

+ 1 - 1
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.intrinsic.vulkan1.1.hlsl

@@ -3,7 +3,7 @@
 // CHECK:      [[file:%\d+]] = OpString
 // CHECK-SAME: spirv.debug.opline.intrinsic.vulkan1.1.hlsl
 
-void main() {
+[numthreads(1,1,1)]void main() {
 // CHECK:      OpLine [[file]] 11 11
 // CHECK:      OpLoad %uint %SubgroupSize
 // CHECK-NEXT: OpLine [[file]] 11 32

+ 1 - 1
tools/clang/test/CodeGenSPIRV/spirv.debug.opline.precedence.hlsl

@@ -3,7 +3,7 @@
 // CHECK:      [[file:%\d+]] = OpString
 // CHECK-SAME: spirv.debug.opline.precedence.hlsl
 
-void main() {
+[numthreads(1,1,1)]void main() {
   int a;
   int b;
 

+ 1 - 0
tools/clang/test/CodeGenSPIRV/type.append.consume-structured-buffer.cast.hlsl

@@ -33,6 +33,7 @@ RWStructuredBuffer<bool2> rw_v2bool;
 ConsumeStructuredBuffer<float2x2> consume_float2x2;
 AppendStructuredBuffer<float4> append_v4float;
 
+[numthreads(1,1,1)]
 void main() {
 // CHECK:       [[p_0:%\d+]] = OpAccessChain %_ptr_Uniform_uint %append_bool %uint_0 {{%\d+}}
 

+ 1 - 0
tools/clang/test/CodeGenSPIRV/type.rwbuffer.half.hlsl

@@ -6,6 +6,7 @@
 
 RWBuffer<half4> HalfBuffer;
 
+[numthreads(1,1,1)]
 void main()
 {
     HalfBuffer[0] = 1.0;

+ 1 - 0
tools/clang/test/CodeGenSPIRV/var.init.vec.size.1.hlsl

@@ -26,6 +26,7 @@ struct S6 {
   bool1 value;
 };
 
+[numthreads(1,1,1)]
 void main() {
   int1 vi;
   float1 vf;

+ 7 - 1
tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

@@ -1172,8 +1172,14 @@ TEST_F(FileTest, AttributePostDepthCoverage) {
 TEST_F(FileTest, AttributeNumThreads) {
   runFileTest("attribute.numthreads.hlsl");
 }
+TEST_F(FileTest, AttributeNumThreadsLib) {
+  runFileTest("attribute.numthreads.lib.hlsl");
+}
 TEST_F(FileTest, AttributeMissingNumThreads) {
-  runFileTest("attribute.numthreads.missing.hlsl");
+  runFileTest("attribute.numthreads.missing.hlsl", Expect::Failure);
+}
+TEST_F(FileTest, AttributeMissingNumThreadsLib) {
+  runFileTest("attribute.numthreads.lib.missing.hlsl", Expect::Failure);
 }
 TEST_F(FileTest, AttributeDomainTri) {
   runFileTest("attribute.domain.tri.hlsl");