Przeglądaj źródła

[spirv] Let .Consume() return access chains (#873)

This will allow further indexing into the struct used to
parameterize ConsumeStructuredBuffer.
Lei Zhang 7 lat temu
rodzic
commit
d0b7c89d87

+ 5 - 5
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -1357,6 +1357,7 @@ SPIRVEmitter::doArraySubscriptExpr(const ArraySubscriptExpr *expr) {
   auto info = doExpr(base);
 
   if (!indices.empty()) {
+    assert(!info.isRValue());
     const uint32_t ptrType = theBuilder.getPointerType(
         typeTranslator.translateType(expr->getType(), info.getLayoutRule()),
         info.getStorageClass());
@@ -2493,12 +2494,9 @@ SPIRVEmitter::processACSBufferAppendConsume(const CXXMemberCallExpr *expr) {
     // Write out the value
     bufferInfo.setResultId(bufferElemPtr);
     storeValue(bufferInfo, doExpr(expr->getArg(0)), bufferElemTy);
-
     return 0;
   } else {
-    return bufferInfo
-        .setResultId(theBuilder.createLoad(bufferElemType, bufferElemPtr))
-        .setRValue();
+    return bufferInfo.setResultId(bufferElemPtr);
   }
 }
 
@@ -2973,6 +2971,7 @@ SPIRVEmitter::doExtMatrixElementExpr(const ExtMatrixElementExpr *expr) {
       const uint32_t ptrType =
           theBuilder.getPointerType(elemType, baseInfo.getStorageClass());
       if (!indices.empty()) {
+        assert(!baseInfo.isRValue());
         // Load the element via access chain
         elem = theBuilder.createAccessChain(ptrType, baseInfo, indices);
       } else {
@@ -3934,7 +3933,7 @@ SPIRVEmitter::tryToAssignToMatrixElements(const Expr *lhs,
     return 0;
 
   const Expr *baseMat = lhsExpr->getBase();
-  const auto &base = doExpr(baseMat);
+  const auto base = doExpr(baseMat);
   const QualType elemType = hlsl::GetHLSLMatElementType(baseMat->getType());
   const uint32_t elemTypeId = typeTranslator.translateType(elemType);
 
@@ -3975,6 +3974,7 @@ SPIRVEmitter::tryToAssignToMatrixElements(const Expr *lhs,
     // chain. base is already the dest pointer.
     uint32_t lhsElemPtr = base;
     if (!indices.empty()) {
+      assert(!base.isRValue());
       // Load the element via access chain
       lhsElemPtr = theBuilder.createAccessChain(ptrType, lhsElemPtr, indices);
     }

+ 14 - 0
tools/clang/test/CodeGenSPIRV/method.consume-structured-buffer.consume.hlsl

@@ -6,8 +6,13 @@ struct S {
     float2x3 c;
 };
 
+struct T {
+    S        s[5];
+};
+
 ConsumeStructuredBuffer<float4> buffer1;
 ConsumeStructuredBuffer<S>      buffer2;
+ConsumeStructuredBuffer<T>      buffer3;
 
 float4 main() : A {
 // CHECK:      [[counter:%\d+]] = OpAccessChain %_ptr_Uniform_int %counter_var_buffer1 %uint_0
@@ -40,5 +45,14 @@ float4 main() : A {
 // CHECK-NEXT: OpStore [[s2]] [[buffer22]]
     s = buffer2.Consume();
 
+// CHECK:      [[counter:%\d+]] = OpAccessChain %_ptr_Uniform_int %counter_var_buffer3 %uint_0
+// CHECK-NEXT: [[prev:%\d+]] = OpAtomicISub %int [[counter]] %uint_1 %uint_0 %int_1
+// CHECK-NEXT: [[index:%\d+]] = OpISub %int [[prev]] %int_1
+// CHECK-NEXT: [[buffer3:%\d+]] = OpAccessChain %_ptr_Uniform_T %buffer3 %uint_0 [[index]]
+// CHECK-NEXT: [[ac:%\d+]] = OpAccessChain %_ptr_Uniform_v3float [[buffer3]] %int_0 %int_3 %int_1
+// CHECK-NEXT: [[val:%\d+]] = OpLoad %v3float [[ac]]
+// CHECK-NEXT: OpStore %val [[val]]
+    float3 val = buffer3.Consume().s[3].b;
+
     return v;
 }