Переглянути джерело

[spirv] Handle GetDimension methods w/ float args. (#944)

Ehsan 7 роки тому
батько
коміт
5362b3597b

+ 22 - 6
tools/clang/lib/SPIRV/SPIRVEmitter.cpp

@@ -2197,6 +2197,24 @@ SPIRVEmitter::processBufferTextureGetDimensions(const CXXMemberCallExpr *expr) {
 
   // For Texture2DMSArray, arguments are: width, height, elements, NumSamples
 
+  // Note: SPIR-V Spec requires return type of OpImageQuerySize(Lod) to be a
+  // scalar/vector of integers. SPIR-V Spec also requires return type of
+  // OpImageQueryLevels and OpImageQuerySamples to be scalar integers.
+  // The HLSL methods, however, have overloaded functions which have float
+  // output arguments. Since the AST naturally won't have casting AST nodes for
+  // such cases, we'll have to perform the cast ourselves.
+  const auto storeToOutputArg = [this](const Expr *outputArg,
+                                       uint32_t toStoreId) {
+    const auto outputArgType = outputArg->getType();
+    // Perform cast to float if necessary.
+    if (isFloatOrVecMatOfFloatType(outputArgType)) {
+      toStoreId = theBuilder.createUnaryOp(
+          spv::Op::OpConvertUToF, typeTranslator.translateType(outputArgType),
+          toStoreId);
+    }
+    theBuilder.createStore(doExpr(outputArg), toStoreId);
+  };
+
   if ((typeName == "Texture1D" && numArgs > 1) ||
       (typeName == "Texture2D" && numArgs > 2) ||
       (typeName == "Texture3D" && numArgs > 3) ||
@@ -2243,7 +2261,7 @@ SPIRVEmitter::processBufferTextureGetDimensions(const CXXMemberCallExpr *expr) {
 
   if (querySize == 1) {
     const uint32_t argIndex = mipLevel ? 1 : 0;
-    theBuilder.createStore(doExpr(expr->getArg(argIndex)), query);
+    storeToOutputArg(expr->getArg(argIndex), query);
   } else {
     for (uint32_t i = 0; i < querySize; ++i) {
       const uint32_t component =
@@ -2251,7 +2269,7 @@ SPIRVEmitter::processBufferTextureGetDimensions(const CXXMemberCallExpr *expr) {
       // If the first arg is the mipmap level, we must write the results
       // starting from Arg(i+1), not Arg(i).
       const uint32_t argIndex = mipLevel ? i + 1 : i;
-      theBuilder.createStore(doExpr(expr->getArg(argIndex)), component);
+      storeToOutputArg(expr->getArg(argIndex), component);
     }
   }
 
@@ -2259,11 +2277,9 @@ SPIRVEmitter::processBufferTextureGetDimensions(const CXXMemberCallExpr *expr) {
     const Expr *numLevelsSamplesArg = numLevels ? numLevels : numSamples;
     const spv::Op opcode =
         numLevels ? spv::Op::OpImageQueryLevels : spv::Op::OpImageQuerySamples;
-    const uint32_t resultType =
-        typeTranslator.translateType(numLevelsSamplesArg->getType());
     const uint32_t numLevelsSamplesQuery =
-        theBuilder.createUnaryOp(opcode, resultType, objectId);
-    theBuilder.createStore(doExpr(numLevelsSamplesArg), numLevelsSamplesQuery);
+        theBuilder.createUnaryOp(opcode, uintId, objectId);
+    storeToOutputArg(numLevelsSamplesArg, numLevelsSamplesQuery);
   }
 
   return 0;

+ 57 - 1
tools/clang/test/CodeGenSPIRV/method.rwtexture.get-dimensions.hlsl

@@ -29,7 +29,7 @@ void main() {
 // CHECK-NEXT: [[query3_0:%\d+]] = OpCompositeExtract %uint [[query3]] 0
 // CHECK-NEXT:                     OpStore %width [[query3_0]]
 // CHECK-NEXT: [[query3_1:%\d+]] = OpCompositeExtract %uint [[query3]] 1
-// CHECK-NEXT:                     OpStore %height [[query3_1]]  
+// CHECK-NEXT:                     OpStore %height [[query3_1]]
   t3.GetDimensions(width, height);
 
 // CHECK:            [[t4:%\d+]] = OpLoad %type_2d_image_array %t4
@@ -51,4 +51,60 @@ void main() {
 // CHECK-NEXT: [[query5_2:%\d+]] = OpCompositeExtract %uint [[query5]] 2
 // CHECK-NEXT:                     OpStore %depth [[query5_2]]
   t5.GetDimensions(width, height, depth);
+
+
+  // Overloads with float output arg.
+  float f_width, f_height, f_depth, f_elements;
+
+// CHECK:            [[t1:%\d+]] = OpLoad %type_1d_image %t1
+// CHECK-NEXT:   [[query1:%\d+]] = OpImageQuerySize %uint [[t1]]
+// CHECK-NEXT: [[f_query1:%\d+]] = OpConvertUToF %float [[query1]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query1]]
+  t1.GetDimensions(f_width);
+
+// CHECK:            [[t2:%\d+]] = OpLoad %type_1d_image_array %t2
+// CHECK-NEXT:   [[query2:%\d+]] = OpImageQuerySize %v2uint [[t2]]
+// CHECK-NEXT: [[query2_0:%\d+]] = OpCompositeExtract %uint [[query2]] 0
+// CHECK-NEXT:[[fquery2_0:%\d+]] = OpConvertUToF %float [[query2_0]]
+// CHECK-NEXT:                     OpStore %f_width [[fquery2_0]]
+// CHECK-NEXT: [[query2_1:%\d+]] = OpCompositeExtract %uint [[query2]] 1
+// CHECK-NEXT:[[fquery2_1:%\d+]] = OpConvertUToF %float [[query2_1]]
+// CHECK-NEXT:                     OpStore %f_elements [[fquery2_1]]
+  t2.GetDimensions(f_width, f_elements);
+
+// CHECK:            [[t3:%\d+]] = OpLoad %type_2d_image %t3
+// CHECK-NEXT:   [[query3:%\d+]] = OpImageQuerySize %v2uint [[t3]]
+// CHECK-NEXT: [[query3_0:%\d+]] = OpCompositeExtract %uint [[query3]] 0
+// CHECK-NEXT:[[fquery3_0:%\d+]] = OpConvertUToF %float [[query3_0]]
+// CHECK-NEXT:                     OpStore %f_width [[fquery3_0]]
+// CHECK-NEXT: [[query3_1:%\d+]] = OpCompositeExtract %uint [[query3]] 1
+// CHECK-NEXT:[[fquery3_1:%\d+]] = OpConvertUToF %float [[query3_1]]
+// CHECK-NEXT:                     OpStore %f_height [[fquery3_1]]  
+  t3.GetDimensions(f_width, f_height);
+
+// CHECK:            [[t4:%\d+]] = OpLoad %type_2d_image_array %t4
+// CHECK-NEXT:   [[query4:%\d+]] = OpImageQuerySize %v3uint [[t4]]
+// CHECK-NEXT: [[query4_0:%\d+]] = OpCompositeExtract %uint [[query4]] 0
+// CHECK-NEXT:[[fquery4_0:%\d+]] = OpConvertUToF %float [[query4_0]]
+// CHECK-NEXT:                     OpStore %f_width [[fquery4_0]]
+// CHECK-NEXT: [[query4_1:%\d+]] = OpCompositeExtract %uint [[query4]] 1
+// CHECK-NEXT:[[fquery4_1:%\d+]] = OpConvertUToF %float [[query4_1]]
+// CHECK-NEXT:                     OpStore %f_height [[fquery4_1]]
+// CHECK-NEXT: [[query4_2:%\d+]] = OpCompositeExtract %uint [[query4]] 2
+// CHECK-NEXT:[[fquery4_2:%\d+]] = OpConvertUToF %float [[query4_2]]
+// CHECK-NEXT:                     OpStore %f_elements [[fquery4_2]]
+  t4.GetDimensions(f_width, f_height, f_elements);
+
+// CHECK:            [[t5:%\d+]] = OpLoad %type_3d_image %t5
+// CHECK-NEXT:   [[query5:%\d+]] = OpImageQuerySize %v3uint [[t5]]
+// CHECK-NEXT: [[query5_0:%\d+]] = OpCompositeExtract %uint [[query5]] 0
+// CHECK-NEXT:[[fquery5_0:%\d+]] = OpConvertUToF %float [[query5_0]]
+// CHECK-NEXT:                     OpStore %f_width [[fquery5_0]]
+// CHECK-NEXT: [[query5_1:%\d+]] = OpCompositeExtract %uint [[query5]] 1
+// CHECK-NEXT:[[fquery5_1:%\d+]] = OpConvertUToF %float [[query5_1]]
+// CHECK-NEXT:                     OpStore %f_height [[fquery5_1]]
+// CHECK-NEXT: [[query5_2:%\d+]] = OpCompositeExtract %uint [[query5]] 2
+// CHECK-NEXT:[[fquery5_2:%\d+]] = OpConvertUToF %float [[query5_2]]
+// CHECK-NEXT:                     OpStore %f_depth [[fquery5_2]]
+  t5.GetDimensions(f_width, f_height, f_depth);
 }

+ 157 - 0
tools/clang/test/CodeGenSPIRV/texture.get-dimensions.hlsl

@@ -132,4 +132,161 @@ void main() {
 // CHECK-NEXT:   [[query17:%\d+]] = OpImageQuerySamples %uint [[t7]]
 // CHECK-NEXT:                      OpStore %numSamples [[query17]]
   t7.GetDimensions(width, height, elements, numSamples);
+
+  // Overloads with float output arg.
+  float f_width, f_height, f_depth, f_elements, f_numSamples, f_numLevels;
+
+// CHECK:          [[t1_0:%\d+]] = OpLoad %type_1d_image %t1
+// CHECK-NEXT:   [[query0:%\d+]] = OpImageQuerySizeLod %uint [[t1_0]] %int_0
+// CHECK-NEXT: [[f_query0:%\d+]] = OpConvertUToF %float [[query0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query0]]
+  t1.GetDimensions(f_width);
+
+// CHECK:        [[t1_1:%\d+]] = OpLoad %type_1d_image %t1
+// CHECK-NEXT:   [[mip0:%\d+]] = OpLoad %uint %mipLevel
+// CHECK-NEXT: [[query1:%\d+]] = OpImageQuerySizeLod %uint [[t1_1]] [[mip0]]
+// CHECK-NEXT: [[f_query1:%\d+]] = OpConvertUToF %float [[query1]]
+// CHECK-NEXT:                   OpStore %f_width [[f_query1]]
+// CHECK-NEXT: [[query2:%\d+]] = OpImageQueryLevels %uint [[t1_1]]
+// CHECK-NEXT: [[f_query2:%\d+]] = OpConvertUToF %float [[query2]]
+// CHECK-NEXT:                   OpStore %f_numLevels [[f_query2]]
+  t1.GetDimensions(mipLevel, f_width, f_numLevels);
+
+// CHECK:          [[t2_0:%\d+]] = OpLoad %type_1d_image_array %t2
+// CHECK-NEXT:   [[query3:%\d+]] = OpImageQuerySizeLod %v2uint [[t2_0]] %int_0
+// CHECK-NEXT: [[query3_0:%\d+]] = OpCompositeExtract %uint [[query3]] 0
+// CHECK-NEXT: [[f_query3_0:%\d+]] = OpConvertUToF %float [[query3_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query3_0]]
+// CHECK-NEXT: [[query3_1:%\d+]] = OpCompositeExtract %uint [[query3]] 1
+// CHECK-NEXT: [[f_query3_1:%\d+]] = OpConvertUToF %float [[query3_1]]
+// CHECK-NEXT:                     OpStore %f_elements [[f_query3_1]]
+  t2.GetDimensions(f_width, f_elements);
+
+// CHECK:          [[t2_1:%\d+]] = OpLoad %type_1d_image_array %t2
+// CHECK-NEXT:     [[mip1:%\d+]] = OpLoad %uint %mipLevel
+// CHECK-NEXT:   [[query4:%\d+]] = OpImageQuerySizeLod %v2uint [[t2_1]] [[mip1]]
+// CHECK-NEXT: [[query4_0:%\d+]] = OpCompositeExtract %uint [[query4]] 0
+// CHECK-NEXT: [[f_query4_0:%\d+]] = OpConvertUToF %float [[query4_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query4_0]]
+// CHECK-NEXT: [[query4_1:%\d+]] = OpCompositeExtract %uint [[query4]] 1
+// CHECK-NEXT: [[f_query4_1:%\d+]] = OpConvertUToF %float [[query4_1]]
+// CHECK-NEXT:                     OpStore %f_elements [[f_query4_1]]
+// CHECK-NEXT:   [[query5:%\d+]] = OpImageQueryLevels %uint [[t2_1]]
+// CHECK-NEXT: [[f_query5:%\d+]] = OpConvertUToF %float [[query5]]
+// CHECK-NEXT:                     OpStore %f_numLevels [[f_query5]]
+  t2.GetDimensions(mipLevel, f_width, f_elements, f_numLevels);
+
+// CHECK:          [[t3_0:%\d+]] = OpLoad %type_2d_image %t3
+// CHECK-NEXT:   [[query5:%\d+]] = OpImageQuerySizeLod %v2uint [[t3_0]] %int_0
+// CHECK-NEXT: [[query5_0:%\d+]] = OpCompositeExtract %uint [[query5]] 0
+// CHECK-NEXT: [[f_query5_0:%\d+]] = OpConvertUToF %float [[query5_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query5_0]]
+// CHECK-NEXT: [[query5_1:%\d+]] = OpCompositeExtract %uint [[query5]] 1
+// CHECK-NEXT: [[f_query5_1:%\d+]] = OpConvertUToF %float [[query5_1]]
+// CHECK-NEXT:                     OpStore %f_height [[f_query5_1]]
+  t3.GetDimensions(f_width, f_height);
+  
+// CHECK:          [[t3_1:%\d+]] = OpLoad %type_2d_image %t3
+// CHECK-NEXT:     [[mip2:%\d+]] = OpLoad %uint %mipLevel
+// CHECK-NEXT:   [[query6:%\d+]] = OpImageQuerySizeLod %v2uint [[t3_1]] [[mip2]]
+// CHECK-NEXT: [[query6_0:%\d+]] = OpCompositeExtract %uint [[query6]] 0
+// CHECK-NEXT: [[f_query6_0:%\d+]] = OpConvertUToF %float [[query6_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query6_0]]
+// CHECK-NEXT: [[query6_1:%\d+]] = OpCompositeExtract %uint [[query6]] 1
+// CHECK-NEXT: [[f_query6_1:%\d+]] = OpConvertUToF %float [[query6_1]]
+// CHECK-NEXT:                     OpStore %f_height [[f_query6_1]]
+// CHECK-NEXT:   [[query7:%\d+]] = OpImageQueryLevels %uint [[t3_1]]
+// CHECK-NEXT: [[f_query7:%\d+]] = OpConvertUToF %float [[query7]]
+// CHECK-NEXT:                     OpStore %f_numLevels [[f_query7]]
+  t3.GetDimensions(mipLevel, f_width, f_height, f_numLevels);
+
+// CHECK:          [[t4_0:%\d+]] = OpLoad %type_2d_image_array %t4
+// CHECK-NEXT:   [[query8:%\d+]] = OpImageQuerySizeLod %v3uint [[t4_0]] %int_0
+// CHECK-NEXT: [[query8_0:%\d+]] = OpCompositeExtract %uint [[query8]] 0
+// CHECK-NEXT: [[f_query8_0:%\d+]] = OpConvertUToF %float [[query8_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query8_0]]
+// CHECK-NEXT: [[query8_1:%\d+]] = OpCompositeExtract %uint [[query8]] 1
+// CHECK-NEXT: [[f_query8_1:%\d+]] = OpConvertUToF %float [[query8_1]]
+// CHECK-NEXT:                     OpStore %f_height [[f_query8_1]]
+// CHECK-NEXT: [[query8_2:%\d+]] = OpCompositeExtract %uint [[query8]] 2
+// CHECK-NEXT: [[f_query8_2:%\d+]] = OpConvertUToF %float [[query8_2]]
+// CHECK-NEXT:                     OpStore %f_elements [[f_query8_2]]
+  t4.GetDimensions(f_width, f_height, f_elements);
+  
+// CHECK:          [[t4_1:%\d+]] = OpLoad %type_2d_image_array %t4
+// CHECK-NEXT:     [[mip3:%\d+]] = OpLoad %uint %mipLevel
+// CHECK-NEXT:   [[query9:%\d+]] = OpImageQuerySizeLod %v3uint [[t4_1]] [[mip3]]
+// CHECK-NEXT: [[query9_0:%\d+]] = OpCompositeExtract %uint [[query9]] 0
+// CHECK-NEXT: [[f_query9_0:%\d+]] = OpConvertUToF %float [[query9_0]]
+// CHECK-NEXT:                     OpStore %f_width [[f_query9_0]]
+// CHECK-NEXT: [[query9_1:%\d+]] = OpCompositeExtract %uint [[query9]] 1
+// CHECK-NEXT: [[f_query9_1:%\d+]] = OpConvertUToF %float [[query9_1]]
+// CHECK-NEXT:                     OpStore %f_height [[f_query9_1]]
+// CHECK-NEXT: [[query9_2:%\d+]] = OpCompositeExtract %uint [[query9]] 2
+// CHECK-NEXT: [[f_query9_2:%\d+]] = OpConvertUToF %float [[query9_2]]
+// CHECK-NEXT:                     OpStore %f_elements [[f_query9_2]]
+// CHECK-NEXT:  [[query10:%\d+]] = OpImageQueryLevels %uint [[t4_1]]
+// CHECK-NEXT: [[f_query10:%\d+]] = OpConvertUToF %float [[query10]]
+// CHECK-NEXT:                     OpStore %f_numLevels [[f_query10]]
+  t4.GetDimensions(mipLevel, f_width, f_height, f_elements, f_numLevels);
+
+// CHECK:           [[t5_0:%\d+]] = OpLoad %type_3d_image %t5
+// CHECK-NEXT:   [[query11:%\d+]] = OpImageQuerySizeLod %v3uint [[t5_0]] %int_0
+// CHECK-NEXT: [[query11_0:%\d+]] = OpCompositeExtract %uint [[query11]] 0
+// CHECK-NEXT: [[f_query11_0:%\d+]] = OpConvertUToF %float [[query11_0]]
+// CHECK-NEXT:                      OpStore %f_width [[f_query11_0]]
+// CHECK-NEXT: [[query11_1:%\d+]] = OpCompositeExtract %uint [[query11]] 1
+// CHECK-NEXT: [[f_query11_1:%\d+]] = OpConvertUToF %float [[query11_1]]
+// CHECK-NEXT:                      OpStore %f_height [[f_query11_1]]
+// CHECK-NEXT: [[query11_2:%\d+]] = OpCompositeExtract %uint [[query11]] 2
+// CHECK-NEXT: [[f_query11_2:%\d+]] = OpConvertUToF %float [[query11_2]]
+// CHECK-NEXT:                      OpStore %f_depth [[f_query11_2]]
+  t5.GetDimensions(f_width, f_height, f_depth);
+
+// CHECK:           [[t5_1:%\d+]] = OpLoad %type_3d_image %t5
+// CHECK-NEXT:      [[mip4:%\d+]] = OpLoad %uint %mipLevel
+// CHECK-NEXT:   [[query12:%\d+]] = OpImageQuerySizeLod %v3uint [[t5_1]] [[mip4]]
+// CHECK-NEXT: [[query12_0:%\d+]] = OpCompositeExtract %uint [[query12]] 0
+// CHECK-NEXT: [[f_query12_0:%\d+]] = OpConvertUToF %float [[query12_0]]
+// CHECK-NEXT:                      OpStore %f_width [[f_query12_0]]
+// CHECK-NEXT: [[query12_1:%\d+]] = OpCompositeExtract %uint [[query12]] 1
+// CHECK-NEXT: [[f_query12_1:%\d+]] = OpConvertUToF %float [[query12_1]]
+// CHECK-NEXT:                      OpStore %f_height [[f_query12_1]]
+// CHECK-NEXT: [[query12_2:%\d+]] = OpCompositeExtract %uint [[query12]] 2
+// CHECK-NEXT: [[f_query12_2:%\d+]] = OpConvertUToF %float [[query12_2]]
+// CHECK-NEXT:                      OpStore %f_depth [[f_query12_2]]
+// CHECK-NEXT:   [[query13:%\d+]] = OpImageQueryLevels %uint [[t5_1]]
+// CHECK-NEXT: [[f_query13:%\d+]] = OpConvertUToF %float [[query13]]
+// CHECK-NEXT:                      OpStore %f_numLevels [[f_query13]]
+  t5.GetDimensions(mipLevel, f_width, f_height, f_depth, f_numLevels);
+
+// CHECK:             [[t6:%\d+]] = OpLoad %type_2d_image_0 %t6
+// CHECK-NEXT:   [[query14:%\d+]] = OpImageQuerySize %v2uint [[t6]]
+// CHECK-NEXT: [[query14_0:%\d+]] = OpCompositeExtract %uint [[query14]] 0
+// CHECK-NEXT: [[f_query14_0:%\d+]] = OpConvertUToF %float [[query14_0]]
+// CHECK-NEXT:                      OpStore %f_width [[f_query14_0]]
+// CHECK-NEXT: [[query14_1:%\d+]] = OpCompositeExtract %uint [[query14]] 1
+// CHECK-NEXT: [[f_query14_1:%\d+]] = OpConvertUToF %float [[query14_1]]
+// CHECK-NEXT:                      OpStore %f_height [[f_query14_1]]
+// CHECK-NEXT:   [[query15:%\d+]] = OpImageQuerySamples %uint [[t6]]
+// CHECK-NEXT: [[f_query15:%\d+]] = OpConvertUToF %float [[query15]]
+// CHECK-NEXT:                      OpStore %f_numSamples [[f_query15]]
+  t6.GetDimensions(f_width, f_height, f_numSamples);
+
+// CHECK:             [[t7:%\d+]] = OpLoad %type_2d_image_array_0 %t7
+// CHECK-NEXT:   [[query16:%\d+]] = OpImageQuerySize %v3uint [[t7]]
+// CHECK-NEXT: [[query16_0:%\d+]] = OpCompositeExtract %uint [[query16]] 0
+// CHECK-NEXT: [[f_query16_0:%\d+]] = OpConvertUToF %float [[query16_0]]
+// CHECK-NEXT:                      OpStore %f_width [[f_query16_0]]
+// CHECK-NEXT: [[query16_1:%\d+]] = OpCompositeExtract %uint [[query16]] 1
+// CHECK-NEXT: [[f_query16_1:%\d+]] = OpConvertUToF %float [[query16_1]]
+// CHECK-NEXT:                      OpStore %f_height [[f_query16_1]]
+// CHECK-NEXT: [[query16_2:%\d+]] = OpCompositeExtract %uint [[query16]] 2
+// CHECK-NEXT: [[f_query16_2:%\d+]] = OpConvertUToF %float [[query16_2]]
+// CHECK-NEXT:                      OpStore %f_elements [[f_query16_2]]
+// CHECK-NEXT:   [[query17:%\d+]] = OpImageQuerySamples %uint [[t7]]
+// CHECK-NEXT: [[f_query17:%\d+]] = OpConvertUToF %float [[query17]]
+// CHECK-NEXT:                      OpStore %f_numSamples [[f_query17]]
+  t7.GetDimensions(f_width, f_height, f_elements, f_numSamples);
+
 }