Преглед изворни кода

[spirv] Fix Memory Barrier mappings to SPIR-V. (#917)

Ehsan пре 7 година
родитељ
комит
8c5a38ba22

+ 60 - 18
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -5473,24 +5473,66 @@ uint32_t SPIRVEmitter::processIntrinsicMemoryBarrier(const CallExpr *callExpr,
                                                      bool isDevice,
                                                      bool groupSync,
                                                      bool isAllBarrier) {
-  // Execution Barrier scope:
-  // Device    = 1
-  // Workgroup = 2
-  // Memory Barrier scope:
-  // Device    = 1
-  // Workgroup = 2
-  // Memory Semantics Barrier scope:
-  // WorkgroupMemory      = 0x100 = 256
-  // CrossWorkgroupMemory = 0x200 = 512
-  // 'All Memory Barrier' must place barrier at several different levels, so
-  // several flags must be turned on:
-  // 0x10 | 0x40 | 0x80 | 0x100 | 0x200 | 0x400 | 0x800 = 0xFD0 = 4048.
-  const uint32_t memSemaMask = isAllBarrier ? 0xFD0 : isDevice ? 0x200 : 0x100;
-  const auto memSema = theBuilder.getConstantUint32(memSemaMask);
-  const auto memScope = isDevice ? theBuilder.getConstantUint32(1)
-                                 : theBuilder.getConstantUint32(2);
-  const auto execScope = groupSync ? memScope : 0;
-  theBuilder.createBarrier(execScope, memScope, memSema);
+  // * DeviceMemoryBarrier =
+  // OpMemoryBarrier (memScope=Device,
+  //                  sem=Image|Uniform|AcquireRelease)
+  //
+  // * DeviceMemoryBarrierWithGroupSync =
+  // OpControlBarrier(execScope = Workgroup,
+  //                  memScope=Device,
+  //                  sem=Image|Uniform|AcquireRelease)
+  const spv::MemorySemanticsMask deviceMemoryBarrierSema =
+      spv::MemorySemanticsMask::ImageMemory |
+      spv::MemorySemanticsMask::UniformMemory |
+      spv::MemorySemanticsMask::AcquireRelease;
+
+  // * GroupMemoryBarrier =
+  // OpMemoryBarrier (memScope=Workgroup,
+  //                  sem = Workgroup|AcquireRelease)
+  //
+  // * GroupMemoryBarrierWithGroupSync =
+  // OpControlBarrier (execScope = Workgroup,
+  //                   memScope = Workgroup,
+  //                   sem = Workgroup|AcquireRelease)
+  const spv::MemorySemanticsMask groupMemoryBarrierSema =
+      spv::MemorySemanticsMask::WorkgroupMemory |
+      spv::MemorySemanticsMask::AcquireRelease;
+
+  // * AllMemoryBarrier =
+  // OpMemoryBarrier(memScope = Device,
+  //                 sem = Image|Uniform|Workgroup|AcquireRelease)
+  //
+  // * AllMemoryBarrierWithGroupSync =
+  // OpControlBarrier(execScope = Workgroup,
+  //                  memScope = Device,
+  //                  sem = Image|Uniform|Workgroup|AcquireRelease)
+  const spv::MemorySemanticsMask allMemoryBarrierSema =
+      spv::MemorySemanticsMask::ImageMemory |
+      spv::MemorySemanticsMask::UniformMemory |
+      spv::MemorySemanticsMask::WorkgroupMemory |
+      spv::MemorySemanticsMask::AtomicCounterMemory |
+      spv::MemorySemanticsMask::AcquireRelease;
+
+  // Get <result-id> for execution scope.
+  // If present, execution scope is always Workgroup!
+  const uint32_t execScopeId =
+      groupSync ? theBuilder.getConstantUint32(
+                      static_cast<uint32_t>(spv::Scope::Workgroup))
+                : 0;
+
+  // Get <result-id> for memory scope
+  const spv::Scope memScope =
+      (isDevice || isAllBarrier) ? spv::Scope::Device : spv::Scope::Workgroup;
+  const uint32_t memScopeId =
+      theBuilder.getConstantUint32(static_cast<uint32_t>(memScope));
+
+  // Get <result-id> for memory semantics
+  const auto memSemaMask = isAllBarrier ? allMemoryBarrierSema
+                                        : isDevice ? deviceMemoryBarrierSema
+                                                   : groupMemoryBarrierSema;
+  const uint32_t memSema =
+      theBuilder.getConstantUint32(static_cast<uint32_t>(memSemaMask));
+  theBuilder.createBarrier(execScopeId, memScopeId, memSema);
   return 0;
 }
 

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

@@ -1,6 +1,9 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Memory scope : Device = 0x1 = 1
+// Semantics: ImageMemory | AtomicCounterMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x400 | 0x40 | 0x100 | 0x8 = 3400
+
 void main() {
-// CHECK: OpMemoryBarrier %uint_1 %uint_4048
+// CHECK: OpMemoryBarrier %uint_1 %uint_3400
   AllMemoryBarrier();
 }

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

@@ -1,6 +1,10 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Execution scope : Workgroup = 0x2 = 2
+// Memory scope : Device = 0x1 = 1
+// Semantics: ImageMemory | AtomicCounterMemory | UniformMemory | WorkgroupMemory | AcquireRelease = 0x800 | 0x400 | 0x40 | 0x100 | 0x8 = 3400
+
 void main() {
-// CHECK: OpControlBarrier %uint_1 %uint_1 %uint_4048
+// CHECK: OpControlBarrier %uint_2 %uint_1 %uint_3400
   AllMemoryBarrierWithGroupSync();
 }

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

@@ -1,6 +1,9 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Memory scope : Device = 0x1 = 1
+// Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
+
 void main() {
-// CHECK: OpMemoryBarrier %uint_1 %uint_512
+// CHECK: OpMemoryBarrier %uint_1 %uint_2120
   DeviceMemoryBarrier();
 }

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

@@ -1,6 +1,10 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Execution scope : Workgroup = 0x2 = 2
+// Memory scope : Device = 0x1 = 1
+// Semantics: ImageMemory | UniformMemory | AcquireRelease = 0x800 | 0x40 | 0x8 = 2120
+
 void main() {
-// CHECK: OpControlBarrier %uint_1 %uint_1 %uint_512
+// CHECK: OpControlBarrier %uint_2 %uint_1 %uint_2120
   DeviceMemoryBarrierWithGroupSync();
 }

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

@@ -1,6 +1,9 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Memory scope : Workgroup = 0x2 = 2
+// Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
+
 void main() {
-// CHECK: OpMemoryBarrier %uint_2 %uint_256
+// CHECK: OpMemoryBarrier %uint_2 %uint_264
   GroupMemoryBarrier();
 }

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

@@ -1,6 +1,10 @@
 // Run: %dxc -T cs_6_0 -E main
 
+// Execution scope : Workgroup = 0x2 = 2
+// Memory scope : Workgroup = 0x2 = 2
+// Semantics: WorkgroupMemory | AcquireRelease = 0x100 | 0x8 = 264
+
 void main() {
-// CHECK: OpControlBarrier %uint_2 %uint_2 %uint_256
+// CHECK: OpControlBarrier %uint_2 %uint_2 %uint_264
   GroupMemoryBarrierWithGroupSync();
 }