瀏覽代碼

[spirv] Always emit a counter variable for RWStructuredBuffer (#896)

This will make handling RWStructuredBuffer aliasing legalization
easier later.
Lei Zhang 7 年之前
父節點
當前提交
d7a96e9e80

+ 15 - 12
tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

@@ -275,24 +275,27 @@ uint32_t DeclResultIdMapper::createFileVar(const VarDecl *var,
 uint32_t DeclResultIdMapper::createExternVar(const VarDecl *var) {
   auto storageClass = spv::StorageClass::UniformConstant;
   auto rule = LayoutRule::Void;
-  bool isACSBuffer = false; // Whether its {Append|Consume}StructuredBuffer
+  bool isACRWSBuffer = false; // Whether its {Append|Consume|RW}StructuredBuffer
 
   if (var->getAttr<HLSLGroupSharedAttr>()) {
     // For CS groupshared variables
     storageClass = spv::StorageClass::Workgroup;
   } else if (auto *t = var->getType()->getAs<RecordType>()) {
     const llvm::StringRef typeName = t->getDecl()->getName();
-    if (typeName == "StructuredBuffer" || typeName == "RWStructuredBuffer" ||
-        typeName == "ByteAddressBuffer" || typeName == "RWByteAddressBuffer" ||
-        typeName == "AppendStructuredBuffer" ||
-        typeName == "ConsumeStructuredBuffer") {
-      // These types are all translated into OpTypeStruct with BufferBlock
-      // decoration. They should follow standard storage buffer layout,
-      // which GLSL std430 rules statisfies.
+
+    // These types are all translated into OpTypeStruct with BufferBlock
+    // decoration. They should follow standard storage buffer layout,
+    // which GLSL std430 rules statisfies.
+    if (typeName == "StructuredBuffer" || typeName == "ByteAddressBuffer" ||
+        typeName == "RWByteAddressBuffer") {
+      storageClass = spv::StorageClass::Uniform;
+      rule = LayoutRule::GLSLStd430;
+    } else if (typeName == "RWStructuredBuffer" ||
+               typeName == "AppendStructuredBuffer" ||
+               typeName == "ConsumeStructuredBuffer") {
       storageClass = spv::StorageClass::Uniform;
       rule = LayoutRule::GLSLStd430;
-      isACSBuffer =
-          typeName.startswith("Append") || typeName.startswith("Consume");
+      isACRWSBuffer = true;
     }
   }
 
@@ -309,8 +312,8 @@ uint32_t DeclResultIdMapper::createExternVar(const VarDecl *var) {
   resourceVars.emplace_back(id, getResourceCategory(var->getType()), regAttr,
                             bindingAttr, counterBindingAttr);
 
-  if (isACSBuffer) {
-    // For {Append|Consume}StructuredBuffer, we need to always create another
+  if (isACRWSBuffer) {
+    // For {Append|Consume|RW}StructuredBuffer, we need to always create another
     // variable for its associated counter.
     createCounterVar(var);
   }

+ 1 - 1
tools/clang/test/CodeGenSPIRV/method.rw-structured-buffer.counter.hlsl

@@ -13,7 +13,7 @@ struct S {
 // CHECK: %counter_var_wCounter2 = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
 RWStructuredBuffer<S> wCounter1;
 RWStructuredBuffer<S> wCounter2;
-// CHECK-NOT: %counter_var_woCounter
+// CHECK: %counter_var_woCounter = OpVariable %_ptr_Uniform_type_ACSBuffer_counter Uniform
 RWStructuredBuffer<S> woCounter;
 
 float4 main() : SV_Target {

+ 8 - 8
tools/clang/test/CodeGenSPIRV/vk.binding.counter.hlsl

@@ -10,6 +10,9 @@ RWStructuredBuffer<S> mySBuffer1;
 // CHECK:      OpDecorate %mySBuffer1 DescriptorSet 3
 // CHECK-NEXT: OpDecorate %mySBuffer1 Binding 5
 
+// CHECK:      OpDecorate %counter_var_mySBuffer1 DescriptorSet 3
+// CHECK-NEXT: OpDecorate %counter_var_mySBuffer1 Binding 10
+
 // :register + vk::counter_binding
 [[vk::counter_binding(20)]]
 AppendStructuredBuffer<S> myASBuffer1 : register(u1, space1);
@@ -28,9 +31,6 @@ RWStructuredBuffer<S> mySBuffer2;
 // CHECK:      OpDecorate %mySBuffer2 DescriptorSet 0
 // CHECK-NEXT: OpDecorate %mySBuffer2 Binding 1
 
-// CHECK:      OpDecorate %counter_var_mySBuffer1 DescriptorSet 3
-// CHECK-NEXT: OpDecorate %counter_var_mySBuffer1 Binding 10
-
 // CHECK-NEXT: OpDecorate %myASBuffer1 DescriptorSet 1
 // CHECK-NEXT: OpDecorate %myASBuffer1 Binding 1
 
@@ -42,19 +42,19 @@ AppendStructuredBuffer<S> myASBuffer2 : register(u3, space2);
 // CHECK-NEXT: OpDecorate %myCSBuffer1 DescriptorSet 0
 // CHECK-NEXT: OpDecorate %myCSBuffer1 Binding 0
 
+// CHECK-NEXT: OpDecorate %counter_var_mySBuffer2 DescriptorSet 0
+// CHECK-NEXT: OpDecorate %counter_var_mySBuffer2 Binding 3
+
 // CHECK-NEXT: OpDecorate %counter_var_myASBuffer2 DescriptorSet 2
 // CHECK-NEXT: OpDecorate %counter_var_myASBuffer2 Binding 0
 
 // none + none
 ConsumeStructuredBuffer<S> myCSBuffer2;
 // CHECK-NEXT: OpDecorate %myCSBuffer2 DescriptorSet 0
-// CHECK-NEXT: OpDecorate %myCSBuffer2 Binding 3
+// CHECK-NEXT: OpDecorate %myCSBuffer2 Binding 4
 
 // CHECK-NEXT: OpDecorate %counter_var_myCSBuffer2 DescriptorSet 0
-// CHECK-NEXT: OpDecorate %counter_var_myCSBuffer2 Binding 4
-
-// CHECK-NEXT: OpDecorate %counter_var_mySBuffer2 DescriptorSet 0
-// CHECK-NEXT: OpDecorate %counter_var_mySBuffer2 Binding 5
+// CHECK-NEXT: OpDecorate %counter_var_myCSBuffer2 Binding 5
 
 float4 main() : SV_Target {
     uint a = mySBuffer1.IncrementCounter();

+ 2 - 0
tools/clang/test/CodeGenSPIRV/vk.binding.explicit.hlsl

@@ -59,6 +59,8 @@ RWStructuredBuffer<S> sbuffer2 : register(u6);
 // CHECK-NEXT: OpDecorate %asbuffer Binding 1
 // CHECK-NEXT: OpDecorate %csbuffer DescriptorSet 1
 // CHECK-NEXT: OpDecorate %csbuffer Binding 21
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 DescriptorSet 3
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 Binding 0
 // CHECK-NEXT: OpDecorate %counter_var_asbuffer DescriptorSet 1
 // CHECK-NEXT: OpDecorate %counter_var_asbuffer Binding 0
 // CHECK-NEXT: OpDecorate %counter_var_csbuffer DescriptorSet 1

+ 6 - 4
tools/clang/test/CodeGenSPIRV/vk.binding.implicit.hlsl

@@ -43,18 +43,20 @@ ConstantBuffer<S> myCbuffer2;
   StructuredBuffer<S> sbuffer1;
 // CHECK:      OpDecorate %sbuffer2 DescriptorSet 0
 // CHECK-NEXT: OpDecorate %sbuffer2 Binding 9
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 DescriptorSet 0
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 Binding 10
 RWStructuredBuffer<S> sbuffer2;
 
 // CHECK:      OpDecorate %abuffer DescriptorSet 0
-// CHECK-NEXT: OpDecorate %abuffer Binding 10
+// CHECK-NEXT: OpDecorate %abuffer Binding 11
 // CHECK-NEXT: OpDecorate %counter_var_abuffer DescriptorSet 0
-// CHECK-NEXT: OpDecorate %counter_var_abuffer Binding 11
+// CHECK-NEXT: OpDecorate %counter_var_abuffer Binding 12
 AppendStructuredBuffer<S> abuffer;
 
 // CHECK:      OpDecorate %csbuffer DescriptorSet 0
-// CHECK-NEXT: OpDecorate %csbuffer Binding 12
+// CHECK-NEXT: OpDecorate %csbuffer Binding 13
 // CHECK-NEXT: OpDecorate %counter_var_csbuffer DescriptorSet 0
-// CHECK-NEXT: OpDecorate %counter_var_csbuffer Binding 13
+// CHECK-NEXT: OpDecorate %counter_var_csbuffer Binding 14
 ConsumeStructuredBuffer<S> csbuffer;
 
 float4 main() : SV_Target {

+ 3 - 0
tools/clang/test/CodeGenSPIRV/vk.binding.register.hlsl

@@ -71,6 +71,9 @@ ConsumeStructuredBuffer<S> csbuffer : register(u7);
 // CHECK:      OpDecorate %sampler4 DescriptorSet 0
 // CHECK-NEXT: OpDecorate %sampler4 Binding 2
 
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 DescriptorSet 1
+// CHECK-NEXT: OpDecorate %counter_var_sbuffer2 Binding 0
+
 // CHECK-NEXT: OpDecorate %counter_var_abuffer DescriptorSet 0
 // CHECK-NEXT: OpDecorate %counter_var_abuffer Binding 4