Skip to content

Commit

Permalink
[spirv] Support flattening descriptor array accessed by var index (#4042
Browse files Browse the repository at this point in the history
)

The existing DXC cannot a flatten descriptor array when an instruction
accesses it using a variable index, because spirv-opt
--descriptor-scalar-replacement pass did not support it. spirv-opt
recently added --replace-desc-array-access-using-var-index that replaces
accesses to descriptor arrays using variable indices with accesses to
constant elements using switch statements. This commit uses the newly
added pass to support flattening all descriptor arrays.
  • Loading branch information
jaebaek authored Oct 28, 2021
1 parent 4652250 commit e343bec
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 2 deletions.
2 changes: 1 addition & 1 deletion external/SPIRV-Tools
Submodule SPIRV-Tools updated 55 files
+0 −90 .appveyor.yml
+2 −0 Android.mk
+4 −0 BUILD.gn
+38 −53 README.md
+17 −3 docs/downloads.md
+7 −0 include/spirv-tools/optimizer.hpp
+4 −0 source/opt/CMakeLists.txt
+51 −46 source/opt/aggressive_dead_code_elim_pass.cpp
+18 −7 source/opt/aggressive_dead_code_elim_pass.h
+1 −1 source/opt/block_merge_pass.cpp
+1 −1 source/opt/convert_to_half_pass.cpp
+1 −1 source/opt/dead_insert_elim_pass.cpp
+30 −3 source/opt/debug_info_manager.cpp
+8 −0 source/opt/decoration_manager.cpp
+4 −0 source/opt/decoration_manager.h
+13 −106 source/opt/desc_sroa.cpp
+0 −9 source/opt/desc_sroa.h
+117 −0 source/opt/desc_sroa_util.cpp
+54 −0 source/opt/desc_sroa_util.h
+1 −1 source/opt/inline_exhaustive_pass.cpp
+1 −1 source/opt/inline_opaque_pass.cpp
+1 −1 source/opt/local_single_block_elim_pass.cpp
+1 −1 source/opt/local_single_store_elim_pass.cpp
+7 −0 source/opt/optimizer.cpp
+1 −0 source/opt/passes.h
+2 −1 source/opt/reflect.h
+1 −1 source/opt/relax_float_ops_pass.cpp
+423 −0 source/opt/replace_desc_array_access_using_var_index.cpp
+204 −0 source/opt/replace_desc_array_access_using_var_index.h
+29 −4 source/opt/set_spec_constant_default_value_pass.cpp
+2 −0 source/val/validate_decorations.cpp
+7 −5 source/val/validate_image.cpp
+34 −11 source/val/validate_interfaces.cpp
+3 −0 test/fuzzers/CMakeLists.txt
+12 −2 test/fuzzers/random_generator.cpp
+12 −1 test/fuzzers/random_generator.h
+80 −0 test/fuzzers/spvtools_fuzz_fuzzer.cpp
+1 −0 test/opt/CMakeLists.txt
+98 −0 test/opt/aggressive_dead_code_elim_test.cpp
+57 −0 test/opt/block_merge_test.cpp
+92 −0 test/opt/convert_relaxed_to_half_test.cpp
+66 −0 test/opt/dead_insert_elim_test.cpp
+116 −0 test/opt/debug_info_manager_test.cpp
+109 −0 test/opt/inline_opaque_test.cpp
+225 −0 test/opt/inline_test.cpp
+16 −0 test/opt/ir_loader_test.cpp
+50 −0 test/opt/local_single_block_elim.cpp
+85 −0 test/opt/local_single_store_elim_test.cpp
+80 −0 test/opt/relax_float_ops_test.cpp
+411 −0 test/opt/replace_desc_array_access_using_var_index_test.cpp
+92 −0 test/opt/set_spec_const_default_value_test.cpp
+30 −0 test/val/val_decoration_test.cpp
+36 −0 test/val/val_image_test.cpp
+62 −0 test/val/val_interfaces_test.cpp
+5 −0 tools/opt/opt.cpp
3 changes: 3 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12593,6 +12593,9 @@ bool SpirvEmitter::spirvToolsLegalize(std::vector<uint32_t> *mod,
// Add flattening of resources if needed.
if (spirvOptions.flattenResourceArrays ||
declIdMapper.requiresFlatteningCompositeResources()) {
optimizer.RegisterPass(
spvtools::CreateReplaceDescArrayAccessUsingVarIndexPass());
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
optimizer.RegisterPass(spvtools::CreateDescriptorScalarReplacementPass());
// ADCE should be run after desc_sroa in order to remove potentially
// illegal types such as structures containing opaque types.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Run: %dxc -T ps_6_0 -E main -fspv-flatten-resource-arrays -O3

// CHECK: OpName %x_0_ "x[0]"
// CHECK: OpName %x_1_ "x[1]"
// CHECK: OpName %y_0_ "y[0]"
// CHECK: OpName %y_1_ "y[1]"
// CHECK: OpName %y_2_ "y[2]"
// CHECK: OpDecorate %x_0_ DescriptorSet 0
// CHECK: OpDecorate %x_0_ Binding 1
// CHECK: OpDecorate %x_1_ DescriptorSet 0
// CHECK: OpDecorate %x_1_ Binding 2
// CHECK: OpDecorate %y_0_ DescriptorSet 0
// CHECK: OpDecorate %y_0_ Binding 2
// CHECK: OpDecorate %y_1_ DescriptorSet 0
// CHECK: OpDecorate %y_1_ Binding 3
// CHECK: OpDecorate %y_2_ DescriptorSet 0
// CHECK: OpDecorate %y_2_ Binding 4

SamplerState x[2] : register(s1);
Texture2D y[3] : register(t2);

float4 main(uint instanceID : INSTANCEID, float2 texCoord : TEXCOORD) : SV_TARGET
{
// CHECK: [[instanceID:%\d+]] = OpLoad %uint %in_var_INSTANCEID
// CHECK: [[texCoord:%\d+]] = OpLoad %v2float %in_var_TEXCOORD
// CHECK: [[instanceID_idx:%\d+]] = OpUMod %uint [[instanceID]] %uint_2
// CHECK: OpSelectionMerge [[merge0:%\d+]] None
// CHECK: OpSwitch [[instanceID_idx]] [[default0:%\d+]] 0 [[sw0_bb0:%\d+]] 1 [[sw0_bb1:%\d+]]
// CHECK: [[sw0_bb0]] = OpLabel
// CHECK: OpSelectionMerge [[merge1:%\d+]] None
// CHECK: OpSwitch [[instanceID]] {{%\d+}} 0 {{%\d+}} 1 {{%\d+}} 2
// CHECK: OpLabel
// CHECK: [[x_0:%\d+]] = OpLoad %type_sampler %x_0_
// CHECK: [[y_0:%\d+]] = OpLoad %type_2d_image %y_0_
// CHECK: [[xy_00:%\d+]] = OpSampledImage %type_sampled_image [[y_0]] [[x_0]]
// CHECK: [[sample0:%\d+]] = OpImageSampleImplicitLod %v4float [[xy_00]] [[texCoord]] None
// CHECK: OpBranch [[merge1]]
// CHECK: OpLabel
// CHECK: OpLoad %type_sampler %x_0_
// CHECK: OpLoad %type_2d_image %y_1_
// CHECK: OpSampledImage %type_sampled_image
// CHECK: OpImageSampleImplicitLod %v4float
// CHECK: OpBranch [[merge1]]
// CHECK: OpLabel
// CHECK: OpLoad %type_sampler %x_0_
// CHECK: OpLoad %type_2d_image %y_2_
// CHECK: OpSampledImage %type_sampled_image
// CHECK: OpImageSampleImplicitLod %v4float
// CHECK: OpBranch [[merge1]]
// CHECK: [[default1:%\d+]] = OpLabel
// CHECK: OpBranch [[merge1]]
// CHECK: [[merge1]] = OpLabel
// CHECK: OpPhi %v4float [[sample0]] {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} [[default1]]
// CHECK: OpBranch [[merge0]]

// CHECK: [[sw0_bb1]] = OpLabel
// CHECK: OpSwitch [[instanceID]]

// CHECK: OpLoad %type_sampler %x_1_
// CHECK: OpLoad %type_2d_image %y_0_
// CHECK: OpImageSampleImplicitLod %v4float %59 [[texCoord]] None

// CHECK: OpLoad %type_sampler %x_1_
// CHECK: OpLoad %type_2d_image %y_1_
// CHECK: OpImageSampleImplicitLod %v4float %63 [[texCoord]] None

// CHECK: OpLoad %type_sampler %x_1_
// CHECK: OpLoad %type_2d_image %y_2_
// CHECK: OpImageSampleImplicitLod %v4float %67 [[texCoord]] None

// CHECK: OpPhi %v4float

// CHECK: OpBranch [[merge0]]
// CHECK: [[default0]] = OpLabel
// CHECK: OpBranch [[merge0]]
// CHECK: [[merge0]] = OpLabel
// CHECK: [[value:%\d+]] = OpPhi %v4float {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} [[default0]]
// CHECK: OpStore %out_var_SV_TARGET [[value]]

return y[instanceID].Sample(x[instanceID % 2], texCoord);
}
3 changes: 3 additions & 0 deletions tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1994,6 +1994,9 @@ TEST_F(FileTest, FlattenResourceArrayBindings2Optimized) {
TEST_F(FileTest, FlattenResourceArrayBindings3) {
runFileTest("vk.binding.cl.flatten-arrays.example3.hlsl");
}
TEST_F(FileTest, FlattenResourceArrayAccessedByVarIndex) {
runFileTest("vk.binding.flatten-arrays.var-index.hlsl");
}

// For testing the "-auto-binding-space" command line option which specifies the
// "default space" for resources.
Expand Down

0 comments on commit e343bec

Please sign in to comment.