Forráskód Böngészése

[spirv] run interface variable SROA if signature packing is enabled (#4442)

Based on the Vulkan spec "15.1.5. Component Assignment":

"A Component decoration must not be specified for any type that is not a
scalar or vector."

we cannot decorate `Component` for array/matrix stage variables, which
is critical for the signature packing. We conduct the scalar replacement
for the stage variables to assign `Component` all stage variables, which
allows us to reduce the number of assigned `Location`s. This commit uses
the interface-variable-scalar-replacement spirv-opt pass for the SROA.

Note that the interface-variable-scalar-replacement spirv-opt pass is
experimental. We want to avoid the side effect caused by the pass as
much as possible. Therefore, we enable the pass only when the option for
the signature packing is enabled.
Jaebaek Seo 3 éve
szülő
commit
bf9632e8c8

+ 1 - 1
external/SPIRV-Headers

@@ -1 +1 @@
-Subproject commit 4995a2f2723c401eb0ea3e10c81298906bf1422b
+Subproject commit b765c355f488837ca4c77980ba69484f3ff277f5

+ 1 - 1
external/SPIRV-Tools

@@ -1 +1 @@
-Subproject commit 67fdf940975eef1a09cc5e6e00ffa7323bf845c4
+Subproject commit ad3514b73237beb75a780ee8922e48798266b98f

+ 7 - 1
tools/clang/lib/SPIRV/SpirvEmitter.cpp

@@ -805,7 +805,8 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) {
       needsLegalization || declIdMapper.requiresLegalization() ||
       spirvOptions.flattenResourceArrays || spirvOptions.reduceLoadSize ||
       declIdMapper.requiresFlatteningCompositeResources() ||
-      !dsetbindingsToCombineImageSampler.empty();
+      !dsetbindingsToCombineImageSampler.empty() ||
+      spirvOptions.signaturePacking;
 
   if (spirvOptions.codeGenHighLevel) {
     beforeHlslLegalization = needsLegalization;
@@ -13074,6 +13075,11 @@ bool SpirvEmitter::spirvToolsLegalize(std::vector<uint32_t> *mod,
 
   spvtools::OptimizerOptions options;
   options.set_run_validator(false);
+  // Add interface variable SROA if the signature packing is enabled.
+  if (spirvOptions.signaturePacking) {
+    optimizer.RegisterPass(
+        spvtools::CreateInterfaceVariableScalarReplacementPass());
+  }
   optimizer.RegisterLegalizationPasses();
   // Add flattening of resources if needed.
   if (spirvOptions.flattenResourceArrays ||

+ 15 - 8
tools/clang/test/CodeGenSPIRV/signature.packing.hlsl

@@ -1,9 +1,9 @@
-// RUN: %dxc -T vs_6_0 -E main -pack-optimized
+// RUN: %dxc -T vs_6_0 -E main -pack-optimized -O0
 
 struct VS_OUTPUT {
   float4 pos : SV_POSITION;
 
-// CHECK: OpDecorate %out_var_A Location 0
+// CHECK-DAG: OpDecorate %out_var_A Location 0
   float a : A;
 
 // CHECK-DAG: OpDecorate %out_var_B Location 0
@@ -11,20 +11,27 @@ struct VS_OUTPUT {
   double b : B;
 
 // CHECK-DAG: OpDecorate %out_var_C Location 1
-  float2 c : C;
+// CHECK-DAG: OpDecorate %out_var_C Component 0
+// CHECK-DAG: OpDecorate %out_var_C_0 Location 2
+// CHECK-DAG: OpDecorate %out_var_C_0 Component 0
+// CHECK-DAG: OpDecorate %out_var_C_1 Location 3
+// CHECK-DAG: OpDecorate %out_var_C_1 Component 0
+  float2 c[3] : C;
 
 // CHECK-DAG: OpDecorate %out_var_D Location 1
 // CHECK-DAG: OpDecorate %out_var_D Component 2
-  float2 d : D;
+// CHECK-DAG: OpDecorate %out_var_D_0 Location 2
+// CHECK-DAG: OpDecorate %out_var_D_0 Component 2
+  float2x2 d : D;
 
-// CHECK-DAG: OpDecorate %out_var_E Location 2
+// CHECK-DAG: OpDecorate %out_var_E Location 3
+// CHECK-DAG: OpDecorate %out_var_E Component 2
   int e : E;
 
-// CHECK-DAG: OpDecorate %out_var_F Location 2
-// CHECK-DAG: OpDecorate %out_var_F Component 1
+// CHECK-DAG: OpDecorate %out_var_F Location 4
   float2 f : F;
 
-// CHECK-DAG: OpDecorate %out_var_G Location 2
+// CHECK-DAG: OpDecorate %out_var_G Location 3
 // CHECK-DAG: OpDecorate %out_var_G Component 3
   float g : G;
 };

+ 37 - 22
tools/clang/test/CodeGenSPIRV/signature.packing.hs.hlsl

@@ -1,56 +1,71 @@
-// RUN: %dxc -T hs_6_0 -E main -pack-optimized
+// RUN: %dxc -T hs_6_0 -E main -pack-optimized -O0
 
 struct HSPatchConstData {
   float tessFactor[3] : SV_TessFactor;
   float insideTessFactor[1] : SV_InsideTessFactor;
 
 // CHECK-DAG: OpDecorate %out_var_A Location 0
-// CHECK-DAG: OpDecorate %out_var_A Patch
   float a : A;
 
 // CHECK-DAG: OpDecorate %out_var_B Location 0
 // CHECK-DAG: OpDecorate %out_var_B Component 2
-// CHECK-DAG: OpDecorate %out_var_B Patch
   double b : B;
 
 // CHECK-DAG: OpDecorate %out_var_C Location 1
-// CHECK-DAG: OpDecorate %out_var_C Patch
-  float2 c : C;
+// CHECK-DAG: OpDecorate %out_var_C Component 0
+// CHECK-DAG: OpDecorate %out_var_C_0 Location 2
+// CHECK-DAG: OpDecorate %out_var_C_0 Component 0
+// CHECK-DAG: OpDecorate %out_var_C_1 Location 3
+// CHECK-DAG: OpDecorate %out_var_C_1 Component 0
+  float2 c[3] : C;
 
 // CHECK-DAG: OpDecorate %out_var_D Location 1
 // CHECK-DAG: OpDecorate %out_var_D Component 2
-// CHECK-DAG: OpDecorate %out_var_D Patch
-  float2 d : D;
+// CHECK-DAG: OpDecorate %out_var_D_0 Location 2
+// CHECK-DAG: OpDecorate %out_var_D_0 Component 2
+  float2x2 d : D;
 
-// CHECK-DAG: OpDecorate %out_var_E Location 2
-// CHECK-DAG: OpDecorate %out_var_E Patch
+// CHECK-DAG: OpDecorate %out_var_E Location 3
+// CHECK-DAG: OpDecorate %out_var_E Component 2
   int e : E;
 
-// CHECK-DAG: OpDecorate %out_var_F Location 2
-// CHECK-DAG: OpDecorate %out_var_F Component 1
-// CHECK-DAG: OpDecorate %out_var_F Patch
+// CHECK-DAG: OpDecorate %out_var_F Location 4
   float2 f : F;
 
-// CHECK-DAG: OpDecorate %out_var_G Location 2
+// CHECK-DAG: OpDecorate %out_var_G Location 3
 // CHECK-DAG: OpDecorate %out_var_G Component 3
-// CHECK-DAG: OpDecorate %out_var_G Patch
   float g : G;
 };
 
 struct HSCtrlPt {
-// CHECK-DAG: OpDecorate %out_var_H Location 3
+// CHECK-DAG: OpDecorate %out_var_H Location 4
+// CHECK-DAG: OpDecorate %out_var_H Component 2
   float h : H;
 
-// CHECK-DAG: OpDecorate %out_var_I Location 3
-// CHECK-DAG: OpDecorate %out_var_I Component 1
+// CHECK-DAG: OpDecorate %out_var_I Location 5
   float2 i : I;
 
-// CHECK-DAG: OpDecorate %out_var_J Location 3
-// CHECK-DAG: OpDecorate %out_var_J Component 3
-  float j : J;
+// CHECK-DAG: OpDecorate %out_var_J Location 6
+// CHECK-DAG: OpDecorate %out_var_J Component 0
+// CHECK-DAG: OpDecorate %out_var_J_0 Location 7
+// CHECK-DAG: OpDecorate %out_var_J_0 Component 0
+// CHECK-DAG: OpDecorate %out_var_J_1 Location 8
+// CHECK-DAG: OpDecorate %out_var_J_1 Component 0
+// CHECK-DAG: OpDecorate %out_var_J_2 Location 9
+// CHECK-DAG: OpDecorate %out_var_J_2 Component 0
+// CHECK-DAG: OpDecorate %out_var_J_3 Location 10
+// CHECK-DAG: OpDecorate %out_var_J_3 Component 0
+  float j[5] : J;
 
-// CHECK-DAG: OpDecorate %out_var_K Location 4
-  float3 k : K;
+// CHECK-DAG: OpDecorate %out_var_K Location 6
+// CHECK-DAG: OpDecorate %out_var_K Component 1
+// CHECK-DAG: OpDecorate %out_var_K_0 Location 7
+// CHECK-DAG: OpDecorate %out_var_K_0 Component 1
+// CHECK-DAG: OpDecorate %out_var_K_1 Location 8
+// CHECK-DAG: OpDecorate %out_var_K_1 Component 1
+// CHECK-DAG: OpDecorate %out_var_K_2 Location 9
+// CHECK-DAG: OpDecorate %out_var_K_2 Component 1
+  float4x3 k : K;
 };
 
 HSPatchConstData HSPatchConstantFunc(const OutputPatch<HSCtrlPt, 3> input) {