浏览代码

[spirv] '++' and '--' for RWTextures/RWBuffers. (#1731)

Ehsan 6 年之前
父节点
当前提交
3a3d16435f

+ 11 - 2
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -4711,7 +4711,9 @@ SpirvEvalInfo SPIRVEmitter::doUnaryOperator(const UnaryOperator *expr) {
     const bool isInc = opcode == UO_PreInc || opcode == UO_PostInc;
 
     const spv::Op spvOp = translateOp(isInc ? BO_Add : BO_Sub, subType);
-    const uint32_t originValue = theBuilder.createLoad(subTypeId, subValue);
+    const uint32_t originValue =
+        subValue.isRValue() ? subValue
+                            : theBuilder.createLoad(subTypeId, subValue);
     const uint32_t one = hlsl::IsHLSLMatType(subType)
                              ? getMatElemValueOne(subType)
                              : getValueOne(subType);
@@ -4729,7 +4731,14 @@ SpirvEvalInfo SPIRVEmitter::doUnaryOperator(const UnaryOperator *expr) {
     } else {
       incValue = theBuilder.createBinaryOp(spvOp, subTypeId, originValue, one);
     }
-    theBuilder.createStore(subValue, incValue);
+
+    // If this is a RWBuffer/RWTexture assignment, OpImageWrite will be used.
+    // Otherwise, store using OpStore.
+    if (tryToAssignToRWBufferRWTexture(subExpr, incValue)) {
+      subValue.setResultId(incValue).setRValue();
+    } else {
+      theBuilder.createStore(subValue, incValue);
+    }
 
     // Prefix increment/decrement operator returns a lvalue, while postfix
     // increment/decrement returns a rvalue.

+ 24 - 0
tools/clang/test/CodeGenSPIRV/unary-op.postfix-dec.hlsl

@@ -2,6 +2,9 @@
 
 // CHECK: [[v3float_1_1_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
 
+RWTexture2D<float>  MyTexture : register(u1);
+RWBuffer<int> intbuf;
+
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
     int a, b;
@@ -31,4 +34,25 @@ void main() {
 // CHECK-NEXT: OpStore %x [[x1]]
 // CHECK-NEXT: OpStore %y [[x0]]
     y = x--;
+
+  uint2 index;
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:   [[vec:%\d+]] = OpImageRead %v4float [[img]] [[index]] None
+// CHECK-NEXT:   [[val:%\d+]] = OpCompositeExtract %float [[vec]] 0
+// CHECK-NEXT:   [[dec:%\d+]] = OpFSub %float [[val]] %float_1
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:                  OpImageWrite [[img]] [[index]] [[dec]]
+// CHECK-NEXT:                  OpStore %s [[val]]
+  float s = MyTexture[index]--;
+
+// CHECK:      [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT: [[vec:%\d+]] = OpImageRead %v4int [[img]] %uint_1 None
+// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %int [[vec]] 0
+// CHECK-NEXT: [[dec:%\d+]] = OpISub %int [[val]] %int_1
+// CHECK-NEXT: [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT:       OpImageWrite [[img]] %uint_1 [[dec]]
+// CHECK-NEXT:       OpStore %t [[val]]
+  int t = intbuf[1]--;
 }

+ 24 - 0
tools/clang/test/CodeGenSPIRV/unary-op.postfix-inc.hlsl

@@ -2,6 +2,9 @@
 
 // CHECK: [[v3float_1_1_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
 
+RWTexture2D<float>  MyTexture : register(u1);
+RWBuffer<int> intbuf;
+
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
     int a, b;
@@ -31,6 +34,27 @@ void main() {
 // CHECK-NEXT: OpStore %x [[x1]]
 // CHECK-NEXT: OpStore %y [[x0]]
     y = x++;
+
+  uint2 index;
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:   [[vec:%\d+]] = OpImageRead %v4float [[img]] [[index]] None
+// CHECK-NEXT:   [[val:%\d+]] = OpCompositeExtract %float [[vec]] 0
+// CHECK-NEXT:   [[inc:%\d+]] = OpFAdd %float [[val]] %float_1
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:                  OpImageWrite [[img]] [[index]] [[inc]]
+// CHECK-NEXT:                  OpStore %r [[val]]
+  float r = MyTexture[index]++;
+
+// CHECK:      [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT: [[vec:%\d+]] = OpImageRead %v4int [[img]] %uint_1 None
+// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %int [[vec]] 0
+// CHECK-NEXT: [[inc:%\d+]] = OpIAdd %int [[val]] %int_1
+// CHECK-NEXT: [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT:       OpImageWrite [[img]] %uint_1 [[inc]]
+// CHECK-NEXT:       OpStore %t [[val]]
+  int t = intbuf[1]++;
 }
 
 

+ 24 - 0
tools/clang/test/CodeGenSPIRV/unary-op.prefix-dec.hlsl

@@ -2,6 +2,9 @@
 
 // CHECK: [[v3float_1_1_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
 
+RWTexture2D<float>  MyTexture : register(u1);
+RWBuffer<int> intbuf;
+
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
     int a, b;
@@ -78,4 +81,25 @@ void main() {
 // CHECK-NEXT: OpStore %x [[x4]]
 // CHECK-NEXT: OpStore %x [[y0]]
     --x = y;
+
+  uint2 index;
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:   [[vec:%\d+]] = OpImageRead %v4float [[img]] [[index]] None
+// CHECK-NEXT:   [[val:%\d+]] = OpCompositeExtract %float [[vec]] 0
+// CHECK-NEXT:   [[dec:%\d+]] = OpFSub %float [[val]] %float_1
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:                  OpImageWrite [[img]] [[index]] [[dec]]
+// CHECK-NEXT:                  OpStore %s [[dec]]
+  float s = --MyTexture[index];
+
+// CHECK:      [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT: [[vec:%\d+]] = OpImageRead %v4int [[img]] %uint_1 None
+// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %int [[vec]] 0
+// CHECK-NEXT: [[dec:%\d+]] = OpISub %int [[val]] %int_1
+// CHECK-NEXT: [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT:       OpImageWrite [[img]] %uint_1 [[dec]]
+// CHECK-NEXT:       OpStore %t [[dec]]
+  int t = --intbuf[1];
 }

+ 24 - 0
tools/clang/test/CodeGenSPIRV/unary-op.prefix-inc.hlsl

@@ -2,6 +2,9 @@
 
 // CHECK: [[v3float_1_1_1:%\d+]] = OpConstantComposite %v3float %float_1 %float_1 %float_1
 
+RWTexture2D<float>  MyTexture : register(u1);
+RWBuffer<int> intbuf;
+
 void main() {
 // CHECK-LABEL: %bb_entry = OpLabel
     int a, b;
@@ -78,4 +81,25 @@ void main() {
 // CHECK-NEXT: OpStore %x [[x4]]
 // CHECK-NEXT: OpStore %x [[y0]]
     ++x = y;
+
+  uint2 index;
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:   [[vec:%\d+]] = OpImageRead %v4float [[img]] [[index]] None
+// CHECK-NEXT:   [[val:%\d+]] = OpCompositeExtract %float [[vec]] 0
+// CHECK-NEXT:   [[inc:%\d+]] = OpFAdd %float [[val]] %float_1
+// CHECK:      [[index:%\d+]] = OpLoad %v2uint %index
+// CHECK-NEXT:   [[img:%\d+]] = OpLoad %type_2d_image %MyTexture
+// CHECK-NEXT:                  OpImageWrite [[img]] [[index]] [[inc]]
+// CHECK-NEXT:                  OpStore %s [[inc]]
+  float s = ++MyTexture[index];
+
+// CHECK:      [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT: [[vec:%\d+]] = OpImageRead %v4int [[img]] %uint_1 None
+// CHECK-NEXT: [[val:%\d+]] = OpCompositeExtract %int [[vec]] 0
+// CHECK-NEXT: [[inc:%\d+]] = OpIAdd %int [[val]] %int_1
+// CHECK-NEXT: [[img:%\d+]] = OpLoad %type_buffer_image %intbuf
+// CHECK-NEXT:       OpImageWrite [[img]] %uint_1 [[inc]]
+// CHECK-NEXT:       OpStore %t [[inc]]
+  int t = ++intbuf[1];
 }