aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/Pipeline/CMakeLists.txt2
-rw-r--r--third_party/SPIRV-Headers/.github/dependabot.yml10
-rw-r--r--third_party/SPIRV-Headers/.github/workflows/presubmit.yml14
-rw-r--r--third_party/SPIRV-Headers/Android.bp5
-rw-r--r--third_party/SPIRV-Headers/BUILD.bazel6
-rw-r--r--third_party/SPIRV-Headers/BUILD.gn3
-rw-r--r--third_party/SPIRV-Headers/CMakeLists.txt14
-rw-r--r--third_party/SPIRV-Headers/LICENSE80
-rw-r--r--third_party/SPIRV-Headers/README.md2
-rw-r--r--third_party/SPIRV-Headers/SECURITY.md13
-rw-r--r--third_party/SPIRV-Headers/include/spirv/spir-v.xml26
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/DebugInfo.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h5
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h57
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json12
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json136
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json2
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.bf169
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json2927
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.cs169
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.h187
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp195
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp11275
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.json190
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.lua158
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spirv.py158
-rw-r--r--third_party/SPIRV-Headers/include/spirv/unified1/spv.d169
-rw-r--r--third_party/SPIRV-Headers/tests/CMakeLists.txt8
-rw-r--r--third_party/SPIRV-Headers/tests/example.cpp2
-rwxr-xr-xthird_party/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py4
-rwxr-xr-xthird_party/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py1
-rwxr-xr-xthird_party/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders2
-rw-r--r--third_party/SPIRV-Headers/tools/buildHeaders/header.cpp79
-rw-r--r--third_party/SPIRV-Headers/tools/buildHeaders/header.h2
-rw-r--r--third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp255
-rw-r--r--third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h16
-rw-r--r--third_party/SPIRV-Headers/tools/buildHeaders/main.cpp2
-rw-r--r--third_party/SPIRV-Tools/.bazelrc7
-rw-r--r--third_party/SPIRV-Tools/.bazelversion2
-rw-r--r--third_party/SPIRV-Tools/.github/dependabot.yml25
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/autoroll.yml10
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/bazel.yml22
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/ios.yml30
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/release.yml3
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/scorecard.yml53
-rw-r--r--third_party/SPIRV-Tools/.github/workflows/wasm.yml2
-rw-r--r--third_party/SPIRV-Tools/.gitignore2
-rw-r--r--third_party/SPIRV-Tools/Android.bp3
-rw-r--r--third_party/SPIRV-Tools/BUILD.bazel96
-rw-r--r--third_party/SPIRV-Tools/BUILD.gn12
-rw-r--r--third_party/SPIRV-Tools/CHANGES145
-rw-r--r--third_party/SPIRV-Tools/CMakeLists.txt55
-rw-r--r--third_party/SPIRV-Tools/CONTRIBUTING.md8
-rw-r--r--third_party/SPIRV-Tools/DEPS13
-rw-r--r--third_party/SPIRV-Tools/MODULE.bazel7
-rw-r--r--third_party/SPIRV-Tools/README.md54
-rw-r--r--third_party/SPIRV-Tools/SECURITY.md13
-rw-r--r--third_party/SPIRV-Tools/WORKSPACE10
-rw-r--r--third_party/SPIRV-Tools/build_defs.bzl12
-rw-r--r--third_party/SPIRV-Tools/docs/downloads.md31
-rw-r--r--third_party/SPIRV-Tools/docs/projects.md4
-rw-r--r--third_party/SPIRV-Tools/external/CMakeLists.txt14
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/instrument.hpp199
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/libspirv.h35
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/libspirv.hpp15
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/linker.hpp36
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/linter.hpp4
-rw-r--r--third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp70
-rw-r--r--third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh16
-rwxr-xr-xthird_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh11
-rw-r--r--third_party/SPIRV-Tools/kokoro/scripts/windows/build.bat17
-rw-r--r--third_party/SPIRV-Tools/source/CMakeLists.txt25
-rw-r--r--third_party/SPIRV-Tools/source/assembly_grammar.cpp21
-rw-r--r--third_party/SPIRV-Tools/source/binary.cpp37
-rw-r--r--third_party/SPIRV-Tools/source/diff/diff.cpp181
-rw-r--r--third_party/SPIRV-Tools/source/disassemble.cpp4
-rw-r--r--third_party/SPIRV-Tools/source/enum_set.h525
-rw-r--r--third_party/SPIRV-Tools/source/ext_inst.cpp10
-rw-r--r--third_party/SPIRV-Tools/source/extensions.cpp5
-rw-r--r--third_party/SPIRV-Tools/source/extensions.h3
-rw-r--r--third_party/SPIRV-Tools/source/fuzz/transformation_add_no_contraction_decoration.cpp5
-rw-r--r--third_party/SPIRV-Tools/source/fuzz/transformation_add_relaxed_decoration.cpp6
-rw-r--r--third_party/SPIRV-Tools/source/link/linker.cpp15
-rw-r--r--third_party/SPIRV-Tools/source/opcode.cpp7
-rw-r--r--third_party/SPIRV-Tools/source/operand.cpp91
-rw-r--r--third_party/SPIRV-Tools/source/operand.h6
-rw-r--r--third_party/SPIRV-Tools/source/opt/CMakeLists.txt8
-rw-r--r--third_party/SPIRV-Tools/source/opt/aggressive_dead_code_elim_pass.cpp12
-rw-r--r--third_party/SPIRV-Tools/source/opt/block_merge_util.cpp11
-rw-r--r--third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp374
-rw-r--r--third_party/SPIRV-Tools/source/opt/constants.cpp27
-rw-r--r--third_party/SPIRV-Tools/source/opt/constants.h6
-rw-r--r--third_party/SPIRV-Tools/source/opt/convert_to_half_pass.cpp31
-rw-r--r--third_party/SPIRV-Tools/source/opt/convert_to_half_pass.h9
-rw-r--r--third_party/SPIRV-Tools/source/opt/copy_prop_arrays.cpp58
-rw-r--r--third_party/SPIRV-Tools/source/opt/copy_prop_arrays.h5
-rw-r--r--third_party/SPIRV-Tools/source/opt/dead_insert_elim_pass.cpp3
-rw-r--r--third_party/SPIRV-Tools/source/opt/decoration_manager.cpp11
-rw-r--r--third_party/SPIRV-Tools/source/opt/decoration_manager.h9
-rw-r--r--third_party/SPIRV-Tools/source/opt/def_use_manager.h22
-rw-r--r--third_party/SPIRV-Tools/source/opt/desc_sroa.cpp49
-rw-r--r--third_party/SPIRV-Tools/source/opt/desc_sroa.h5
-rw-r--r--third_party/SPIRV-Tools/source/opt/feature_manager.cpp20
-rw-r--r--third_party/SPIRV-Tools/source/opt/feature_manager.h47
-rw-r--r--third_party/SPIRV-Tools/source/opt/fix_storage_class.cpp8
-rw-r--r--third_party/SPIRV-Tools/source/opt/fold.cpp125
-rw-r--r--third_party/SPIRV-Tools/source/opt/fold.h8
-rw-r--r--third_party/SPIRV-Tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp22
-rw-r--r--third_party/SPIRV-Tools/source/opt/folding_rules.cpp23
-rw-r--r--third_party/SPIRV-Tools/source/opt/graphics_robust_access_pass.cpp6
-rw-r--r--third_party/SPIRV-Tools/source/opt/inline_pass.cpp13
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp832
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.h120
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp365
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.h18
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp253
-rw-r--r--third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.h115
-rw-r--r--third_party/SPIRV-Tools/source/opt/instruction.cpp28
-rw-r--r--third_party/SPIRV-Tools/source/opt/instruction.h10
-rw-r--r--third_party/SPIRV-Tools/source/opt/instrument_pass.cpp594
-rw-r--r--third_party/SPIRV-Tools/source/opt/instrument_pass.h233
-rw-r--r--third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.cpp493
-rw-r--r--third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.h158
-rw-r--r--third_party/SPIRV-Tools/source/opt/ir_builder.h16
-rw-r--r--third_party/SPIRV-Tools/source/opt/ir_context.cpp61
-rw-r--r--third_party/SPIRV-Tools/source/opt/ir_context.h60
-rw-r--r--third_party/SPIRV-Tools/source/opt/local_access_chain_convert_pass.cpp9
-rw-r--r--third_party/SPIRV-Tools/source/opt/local_single_block_elim_pass.cpp8
-rw-r--r--third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp8
-rw-r--r--third_party/SPIRV-Tools/source/opt/log.h27
-rw-r--r--third_party/SPIRV-Tools/source/opt/mem_pass.cpp5
-rw-r--r--third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.cpp103
-rw-r--r--third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.h53
-rw-r--r--third_party/SPIRV-Tools/source/opt/module.h9
-rw-r--r--third_party/SPIRV-Tools/source/opt/optimizer.cpp214
-rw-r--r--third_party/SPIRV-Tools/source/opt/passes.h4
-rw-r--r--third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.cpp46
-rw-r--r--third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.h52
-rw-r--r--third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.cpp649
-rw-r--r--third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.h205
-rw-r--r--third_party/SPIRV-Tools/source/opt/type_manager.cpp97
-rw-r--r--third_party/SPIRV-Tools/source/opt/type_manager.h15
-rw-r--r--third_party/SPIRV-Tools/source/opt/types.cpp42
-rw-r--r--third_party/SPIRV-Tools/source/opt/types.h35
-rw-r--r--third_party/SPIRV-Tools/source/parsed_operand.cpp1
-rw-r--r--third_party/SPIRV-Tools/source/print.cpp2
-rw-r--r--third_party/SPIRV-Tools/source/table.h2
-rw-r--r--third_party/SPIRV-Tools/source/text.cpp18
-rw-r--r--third_party/SPIRV-Tools/source/val/validate.cpp9
-rw-r--r--third_party/SPIRV-Tools/source/val/validate.h27
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_annotation.cpp31
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_arithmetics.cpp153
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_atomics.cpp50
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_builtins.cpp182
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_capability.cpp2
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_cfg.cpp96
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_composites.cpp24
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_constants.cpp2
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_conversion.cpp18
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_decorations.cpp115
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_extensions.cpp26
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_id.cpp14
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_image.cpp291
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_instruction.cpp24
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_interfaces.cpp110
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_memory.cpp281
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_memory_semantics.cpp5
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_mode_setting.cpp252
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_non_uniform.cpp369
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_scopes.cpp8
-rw-r--r--third_party/SPIRV-Tools/source/val/validate_type.cpp70
-rw-r--r--third_party/SPIRV-Tools/source/val/validation_state.cpp271
-rw-r--r--third_party/SPIRV-Tools/source/val/validation_state.h41
-rwxr-xr-xthird_party/SPIRV-Tools/source/wasm/build.sh2
-rw-r--r--third_party/SPIRV-Tools/test/CMakeLists.txt22
-rw-r--r--third_party/SPIRV-Tools/test/binary_parse_test.cpp5
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/basic_autogen.cpp10
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/constant_array_size_autogen.cpp4
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/diff_test_files_autogen.cmake1
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_fragment_autogen.cpp44
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_vertex_autogen.cpp71
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/different_function_parameter_count_autogen.cpp34
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/extra_if_block_autogen.cpp68
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/int_vs_uint_constants_autogen.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/multiple_same_entry_points_autogen.cpp9
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_autogen.cpp148
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_dst.spvasm18
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_src.spvasm16
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/reordered_if_blocks_autogen.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/reordered_switch_blocks_autogen.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/diff/diff_files/spec_constant_array_size_autogen.cpp20
-rw-r--r--third_party/SPIRV-Tools/test/enum_set_test.cpp806
-rw-r--r--third_party/SPIRV-Tools/test/fuzz/transformation_add_no_contraction_decoration_test.cpp8
-rw-r--r--third_party/SPIRV-Tools/test/fuzz/transformation_add_opphi_synonym_test.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/fuzz/transformation_add_relaxed_decoration_test.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/fuzz/transformation_add_type_float_test.cpp2
-rw-r--r--third_party/SPIRV-Tools/test/fuzz/transformation_add_type_int_test.cpp4
-rw-r--r--third_party/SPIRV-Tools/test/link/binary_version_test.cpp16
-rw-r--r--third_party/SPIRV-Tools/test/log_test.cpp53
-rw-r--r--third_party/SPIRV-Tools/test/operand_capabilities_test.cpp162
-rw-r--r--third_party/SPIRV-Tools/test/opt/CMakeLists.txt13
-rw-r--r--third_party/SPIRV-Tools/test/opt/aggressive_dead_code_elim_test.cpp110
-rw-r--r--third_party/SPIRV-Tools/test/opt/amd_ext_to_khr.cpp21
-rw-r--r--third_party/SPIRV-Tools/test/opt/block_merge_test.cpp142
-rw-r--r--third_party/SPIRV-Tools/test/opt/convert_relaxed_to_half_test.cpp169
-rw-r--r--third_party/SPIRV-Tools/test/opt/copy_prop_array_test.cpp35
-rw-r--r--third_party/SPIRV-Tools/test/opt/dead_insert_elim_test.cpp107
-rw-r--r--third_party/SPIRV-Tools/test/opt/desc_sroa_test.cpp68
-rw-r--r--third_party/SPIRV-Tools/test/opt/feature_manager_test.cpp37
-rw-r--r--third_party/SPIRV-Tools/test/opt/fix_storage_class_test.cpp41
-rw-r--r--third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp130
-rw-r--r--third_party/SPIRV-Tools/test/opt/fold_test.cpp1180
-rw-r--r--third_party/SPIRV-Tools/test/opt/inline_test.cpp49
-rw-r--r--third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp5354
-rw-r--r--third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp684
-rw-r--r--third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp104
-rw-r--r--third_party/SPIRV-Tools/test/opt/invocation_interlock_placement_test.cpp613
-rw-r--r--third_party/SPIRV-Tools/test/opt/ir_context_test.cpp248
-rw-r--r--third_party/SPIRV-Tools/test/opt/modify_maximal_reconvergence_test.cpp312
-rw-r--r--third_party/SPIRV-Tools/test/opt/switch_descriptorset_test.cpp193
-rw-r--r--third_party/SPIRV-Tools/test/opt/trim_capabilities_pass_test.cpp2665
-rw-r--r--third_party/SPIRV-Tools/test/opt/type_manager_test.cpp47
-rw-r--r--third_party/SPIRV-Tools/test/scripts/test_compact_ids.py4
-rw-r--r--third_party/SPIRV-Tools/test/text_to_binary.extension_test.cpp53
-rw-r--r--third_party/SPIRV-Tools/test/text_to_binary.pipe_storage_test.cpp6
-rw-r--r--third_party/SPIRV-Tools/test/tools/CMakeLists.txt4
-rw-r--r--third_party/SPIRV-Tools/test/tools/opt/CMakeLists.txt4
-rw-r--r--third_party/SPIRV-Tools/test/unit_spirv.h5
-rw-r--r--third_party/SPIRV-Tools/test/val/CMakeLists.txt1
-rw-r--r--third_party/SPIRV-Tools/test/val/val_annotation_test.cpp165
-rw-r--r--third_party/SPIRV-Tools/test/val/val_arithmetics_test.cpp151
-rw-r--r--third_party/SPIRV-Tools/test/val/val_atomics_test.cpp142
-rw-r--r--third_party/SPIRV-Tools/test/val/val_barriers_test.cpp38
-rw-r--r--third_party/SPIRV-Tools/test/val/val_builtins_test.cpp254
-rw-r--r--third_party/SPIRV-Tools/test/val/val_cfg_test.cpp315
-rw-r--r--third_party/SPIRV-Tools/test/val/val_composites_test.cpp86
-rw-r--r--third_party/SPIRV-Tools/test/val/val_conversion_test.cpp176
-rw-r--r--third_party/SPIRV-Tools/test/val/val_decoration_test.cpp192
-rw-r--r--third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp18
-rw-r--r--third_party/SPIRV-Tools/test/val/val_extension_spv_nv_raw_access_chains.cpp510
-rw-r--r--third_party/SPIRV-Tools/test/val/val_extensions_test.cpp208
-rw-r--r--third_party/SPIRV-Tools/test/val/val_id_test.cpp25
-rw-r--r--third_party/SPIRV-Tools/test/val/val_image_test.cpp3992
-rw-r--r--third_party/SPIRV-Tools/test/val/val_interfaces_test.cpp109
-rw-r--r--third_party/SPIRV-Tools/test/val/val_memory_test.cpp254
-rw-r--r--third_party/SPIRV-Tools/test/val/val_modes_test.cpp902
-rw-r--r--third_party/SPIRV-Tools/test/val/val_non_uniform_test.cpp741
-rw-r--r--third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp89
-rw-r--r--third_party/SPIRV-Tools/tools/fuzz/fuzz.cpp11
-rw-r--r--third_party/SPIRV-Tools/tools/io.h1
-rw-r--r--third_party/SPIRV-Tools/tools/link/linker.cpp9
-rw-r--r--third_party/SPIRV-Tools/tools/opt/opt.cpp24
-rw-r--r--third_party/SPIRV-Tools/tools/reduce/reduce.cpp13
-rw-r--r--third_party/SPIRV-Tools/tools/sva/package.json10
-rw-r--r--third_party/SPIRV-Tools/tools/sva/src/spirv.data.js3
-rw-r--r--third_party/SPIRV-Tools/tools/sva/yarn.lock2216
-rwxr-xr-xthird_party/SPIRV-Tools/utils/check_copyright.py2
-rwxr-xr-xthird_party/SPIRV-Tools/utils/check_symbol_exports.py2
-rwxr-xr-xthird_party/SPIRV-Tools/utils/fixup_fuzz_result.py2
-rw-r--r--third_party/SPIRV-Tools/utils/generate_changelog.py2
-rwxr-xr-xthird_party/SPIRV-Tools/utils/generate_grammar_tables.py4
-rwxr-xr-xthird_party/SPIRV-Tools/utils/generate_language_headers.py2
-rwxr-xr-xthird_party/SPIRV-Tools/utils/generate_registry_tables.py10
-rwxr-xr-xthird_party/SPIRV-Tools/utils/generate_vim_syntax.py2
-rwxr-xr-xthird_party/SPIRV-Tools/utils/roll_deps.sh1
-rwxr-xr-xthird_party/SPIRV-Tools/utils/update_build_version.py45
-rw-r--r--third_party/llvm-16.0/configs/linux/include/llvm/Config/config.h2
-rwxr-xr-xthird_party/update-spirvtools.sh2
284 files changed, 30882 insertions, 9512 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 434fbb708..c5cd16d55 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -803,6 +803,7 @@ if (NOT TARGET SPIRV-Tools)
set(SPIRV-Headers_SOURCE_DIR "${THIRD_PARTY_DIR}/SPIRV-Headers")
set(SPIRV_SKIP_TESTS TRUE CACHE BOOL "" FORCE)
set(SPIRV_SKIP_EXECUTABLES TRUE CACHE BOOL "" FORCE)
+ set(SPIRV_WERROR FALSE CACHE BOOL "" FORCE)
add_subdirectory(${THIRD_PARTY_DIR}/SPIRV-Tools) # Add SPIRV-Tools target
endif()
diff --git a/src/Pipeline/CMakeLists.txt b/src/Pipeline/CMakeLists.txt
index c440a8c02..374d42467 100644
--- a/src/Pipeline/CMakeLists.txt
+++ b/src/Pipeline/CMakeLists.txt
@@ -74,8 +74,6 @@ endif()
set_target_properties(core_tables PROPERTIES FOLDER "SPIRV-Tools build")
set_target_properties(enum_string_mapping PROPERTIES FOLDER "SPIRV-Tools build")
set_target_properties(extinst_tables PROPERTIES FOLDER "SPIRV-Tools build")
-set_target_properties(spirv-tools-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
-set_target_properties(spirv-tools-shared-pkg-config PROPERTIES FOLDER "SPIRV-Tools build")
set_target_properties(vk_pipeline PROPERTIES
POSITION_INDEPENDENT_CODE 1
diff --git a/third_party/SPIRV-Headers/.github/dependabot.yml b/third_party/SPIRV-Headers/.github/dependabot.yml
new file mode 100644
index 000000000..2390d8c80
--- /dev/null
+++ b/third_party/SPIRV-Headers/.github/dependabot.yml
@@ -0,0 +1,10 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "monthly"
+ groups:
+ github-actions:
+ patterns:
+ - "*"
diff --git a/third_party/SPIRV-Headers/.github/workflows/presubmit.yml b/third_party/SPIRV-Headers/.github/workflows/presubmit.yml
index 306f50ee5..d7958ca75 100644
--- a/third_party/SPIRV-Headers/.github/workflows/presubmit.yml
+++ b/third_party/SPIRV-Headers/.github/workflows/presubmit.yml
@@ -12,7 +12,7 @@ jobs:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- name: Install Ubuntu packages
if: matrix.os == 'ubuntu-latest'
run: sudo apt install -y dos2unix
@@ -42,7 +42,7 @@ jobs:
test_cmake_min_required:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.14.0
@@ -54,7 +54,7 @@ jobs:
test_cmake_latest:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
- name: CMake build
run: |
@@ -64,7 +64,7 @@ jobs:
add_subdirectory:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.15.0
@@ -76,7 +76,7 @@ jobs:
find_package:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.15.0
@@ -92,7 +92,7 @@ jobs:
find_pkg_config:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.15.0
@@ -109,7 +109,7 @@ jobs:
find_pkg_config_absolute:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.15.0
diff --git a/third_party/SPIRV-Headers/Android.bp b/third_party/SPIRV-Headers/Android.bp
index 74b93b48e..3e6167127 100644
--- a/third_party/SPIRV-Headers/Android.bp
+++ b/third_party/SPIRV-Headers/Android.bp
@@ -97,6 +97,11 @@ filegroup {
}
filegroup {
+ name: "swiftshader_spirv_headers_unified1_extinst.nonsemantic.vkspreflection.grammar.json",
+ srcs: ["include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json"],
+}
+
+filegroup {
name: "swiftshader_spirv_headers_unified1_extinst.nonsemantic.shader.debuginfo.100.grammar.json",
srcs: ["include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json"],
}
diff --git a/third_party/SPIRV-Headers/BUILD.bazel b/third_party/SPIRV-Headers/BUILD.bazel
index c898ade80..25634d948 100644
--- a/third_party/SPIRV-Headers/BUILD.bazel
+++ b/third_party/SPIRV-Headers/BUILD.bazel
@@ -82,6 +82,11 @@ filegroup(
)
filegroup(
+ name = "spirv_ext_inst_nonsemantic_vkspreflection_grammar_unified1",
+ srcs = ["include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json"],
+)
+
+filegroup(
name = "spirv_ext_inst_nonsemantic_debugprintf_grammar_unified1",
srcs = ["include/spirv/unified1/extinst.nonsemantic.debugprintf.grammar.json"],
)
@@ -128,6 +133,7 @@ cc_library(
"include/spirv/unified1/GLSL.std.450.h",
"include/spirv/unified1/NonSemanticClspvReflection.h",
"include/spirv/unified1/NonSemanticDebugPrintf.h",
+ "include/spirv/unified1/NonSemanticVkspReflection.h",
"include/spirv/unified1/OpenCL.std.h",
],
includes = ["include"],
diff --git a/third_party/SPIRV-Headers/BUILD.gn b/third_party/SPIRV-Headers/BUILD.gn
index be3f43b3f..34294e023 100644
--- a/third_party/SPIRV-Headers/BUILD.gn
+++ b/third_party/SPIRV-Headers/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright (c) 2020 Google LLC
+# Copyright (c) 2020-2024 Google LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and/or associated documentation files (the "Materials"),
@@ -35,6 +35,7 @@ source_set("spv_headers") {
"include/spirv/unified1/GLSL.std.450.h",
"include/spirv/unified1/NonSemanticClspvReflection.h",
"include/spirv/unified1/NonSemanticDebugPrintf.h",
+ "include/spirv/unified1/NonSemanticVkspReflection.h",
"include/spirv/unified1/OpenCL.std.h",
"include/spirv/unified1/spirv.h",
"include/spirv/unified1/spirv.hpp",
diff --git a/third_party/SPIRV-Headers/CMakeLists.txt b/third_party/SPIRV-Headers/CMakeLists.txt
index e3d76d944..b018b23fa 100644
--- a/third_party/SPIRV-Headers/CMakeLists.txt
+++ b/third_party/SPIRV-Headers/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2015-2023 The Khronos Group Inc.
+# Copyright (c) 2015-2024 The Khronos Group Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and/or associated documentation files (the
@@ -35,12 +35,14 @@ add_library(SPIRV-Headers INTERFACE)
add_library(SPIRV-Headers::SPIRV-Headers ALIAS SPIRV-Headers)
target_include_directories(SPIRV-Headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
-if (PROJECT_IS_TOP_LEVEL)
- option(BUILD_TESTS "Build the tests")
- if (BUILD_TESTS)
- add_subdirectory(tests)
- endif()
+option(SPIRV_HEADERS_ENABLE_TESTS "Test SPIRV-Headers" ${PROJECT_IS_TOP_LEVEL})
+option(SPIRV_HEADERS_ENABLE_INSTALL "Install SPIRV-Headers" ${PROJECT_IS_TOP_LEVEL})
+
+if(SPIRV_HEADERS_ENABLE_TESTS)
+ add_subdirectory(tests)
+endif()
+if(SPIRV_HEADERS_ENABLE_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
diff --git a/third_party/SPIRV-Headers/LICENSE b/third_party/SPIRV-Headers/LICENSE
index 47974f8ce..a02ace17b 100644
--- a/third_party/SPIRV-Headers/LICENSE
+++ b/third_party/SPIRV-Headers/LICENSE
@@ -1,4 +1,5 @@
-Copyright (c) 2015-2018 The Khronos Group Inc.
+Files: All files except for those called out below.
+Copyright (c) 2015-2024 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
@@ -23,3 +24,80 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+---
+
+Files: include/spirv/spir-v.xml
+Copyright (c) 2015-2024 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and/or associated documentation files (the
+"Materials"), to deal in the Materials without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Materials, and to
+permit persons to whom the Materials are furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Materials.
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+
+---
+
+Files: tools/buildHeaders/jsoncpp/*
+The JsonCpp library's source code, including accompanying documentation,
+tests and demonstration applications, are licensed under the following
+conditions...
+
+The author (Baptiste Lepilleur) explicitly disclaims copyright in all
+jurisdictions which recognize such a disclaimer. In such jurisdictions,
+this software is released into the Public Domain.
+
+In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
+2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
+released under the terms of the MIT License (see below).
+
+In jurisdictions which recognize Public Domain property, the user of this
+software may choose to accept it either as 1) Public Domain, 2) under the
+conditions of the MIT License (see below), or 3) under the terms of dual
+Public Domain/MIT License conditions described here, as they choose.
+
+The MIT License is about as close to Public Domain as a license can get, and is
+described in clear, concise terms at:
+
+ http://en.wikipedia.org/wiki/MIT_License
+
+The full text of the MIT License follows:
+
+========================================================================
+Copyright (c) 2007-2010 Baptiste Lepilleur
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy,
+modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+========================================================================
+
+---
diff --git a/third_party/SPIRV-Headers/README.md b/third_party/SPIRV-Headers/README.md
index 8c7039f7d..ed3882856 100644
--- a/third_party/SPIRV-Headers/README.md
+++ b/third_party/SPIRV-Headers/README.md
@@ -198,7 +198,7 @@ python3 bin/makeExtinstHeaders.py
## License
<a name="license"></a>
```
-Copyright (c) 2015-2018 The Khronos Group Inc.
+Copyright (c) 2015-2024 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/SECURITY.md b/third_party/SPIRV-Headers/SECURITY.md
new file mode 100644
index 000000000..9b51f0cf0
--- /dev/null
+++ b/third_party/SPIRV-Headers/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+## Supported Versions
+
+Security updates are applied only to the latest release.
+
+## Reporting a Vulnerability
+
+If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
+
+Please disclose it at [security advisory](https://github.com/KhronosGroup/SPIRV-Headers/security/advisories/new).
+
+This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
diff --git a/third_party/SPIRV-Headers/include/spirv/spir-v.xml b/third_party/SPIRV-Headers/include/spirv/spir-v.xml
index 9dea8d9bb..52de097a3 100644
--- a/third_party/SPIRV-Headers/include/spirv/spir-v.xml
+++ b/third_party/SPIRV-Headers/include/spirv/spir-v.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<registry>
<!--
- Copyright (c) 2015 The Khronos Group Inc.
+ Copyright (c) 2015-2024 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
@@ -82,12 +82,19 @@
<id value="29" vendor="Mikkosoft Productions" tool="MSP Shader Compiler" comment="Contact Mikko Rasa, tdb@tdb.fi"/>
<id value="30" vendor="SpvGenTwo community" tool="SpvGenTwo SPIR-V IR Tools" comment="https://github.com/rAzoR8/SpvGenTwo"/>
<id value="31" vendor="Google" tool="Skia SkSL" comment="Contact Ethan Nicholas, ethannicholas@google.com"/>
- <id value="32" vendor="TornadoVM" tool="SPIRV Beehive Toolkit" comment="https://github.com/beehive-lab/spirv-beehive-toolkit"/>
+ <id value="32" vendor="TornadoVM" tool="Beehive SPIRV Toolkit" comment="https://github.com/beehive-lab/beehive-spirv-toolkit"/>
<id value="33" vendor="DragonJoker" tool="ShaderWriter" comment="Contact Sylvain Doremus, https://github.com/DragonJoker/ShaderWriter"/>
<id value="34" vendor="Rayan Hatout" tool="SPIRVSmith" comment="Contact Rayan Hatout rayan.hatout@gmail.com, Repo https://github.com/rayanht/SPIRVSmith"/>
<id value="35" vendor="Saarland University" tool="Shady" comment="Contact Hugo Devillers devillers@uni-saarland.de, Repo https://github.com/Hugobros3/shady"/>
<id value="36" vendor="Taichi Graphics" tool="Taichi" comment="Contact Rendong Liang rendongliang@taichi.graphics, Repo https://github.com/taichi-dev/taichi"/>
- <unused start="37" end="0xFFFF" comment="Tool ID range reservable for future use by vendors"/>
+ <id value="37" vendor="heroseh" tool="Hero C Compiler" comment="https://github.com/heroseh/hcc"/>
+ <id value="38" vendor="Meta" tool="SparkSL" comment="Contact Dunfan Lu, dunfanlu@meta.com, https://sparkar.facebook.com/ar-studio/learn/sparksl/sparksl-overview"/>
+ <id value="39" vendor="SirLynix" tool="Nazara ShaderLang Compiler" comment="Contact Jérôme Leclercq, https://github.com/NazaraEngine/ShaderLang"/>
+ <id value="40" vendor="NVIDIA" tool="Slang Compiler" comment="Contact Theresa Foley, tfoley@nvidia.com, https://github.com/shader-slang/slang/"/>
+ <id value="41" vendor="Zig Software Foundation" tool="Zig Compiler" comment="Contact Robin Voetter, https://github.com/Snektron"/>
+ <id value="42" vendor="Rendong Liang" tool="spq" comment="Contact Rendong Liang, admin@penguinliong.moe, https://github.com/PENGUINLIONG/spq-rs"/>
+ <id value="43" vendor="LLVM" tool="LLVM SPIR-V Backend" comment="Contact Michal Paszkowski, michal.paszkowski@intel.com, https://github.com/llvm/llvm-project/tree/main/llvm/lib/Target/SPIRV"/>
+ <unused start="44" end="0xFFFF" comment="Tool ID range reservable for future use by vendors"/>
</ids>
<!-- SECTION: SPIR-V Opcodes and Enumerants -->
@@ -143,6 +150,7 @@
<ids type="opcode" start="6464" end="6527" vendor="N/A" comment="Blank range to keep alignment with non-opcodes"/>
<ids type="opcode" start="6528" end="6591" vendor="Codeplay" comment="Contact duncan.brawley@codeplay.com"/>
<ids type="opcode" start="6592" end="6655" vendor="Saarland University" comment="Contact devillers@cg.uni-saarland.de"/>
+ <ids type="opcode" start="6656" end="6719" vendor="Meta" comment="Contact dunfanlu@meta.com"/>
<!-- Opcode enumerants to reserve for future use. To get a block, allocate
multiples of 64 starting at the lowest available point in this
block and add a corresponding <ids> tag immediately above. Make
@@ -175,6 +183,7 @@
<ids type="enumerant" start="6464" end="6527" vendor="Mikkosoft Productions" comment="Contact Mikko Rasa, tdb@tdb.fi"/>
<ids type="enumerant" start="6528" end="6591" vendor="Codeplay" comment="Contact duncan.brawley@codeplay.com"/>
<ids type="enumerant" start="6592" end="6655" vendor="Saarland University" comment="Contact devillers@cg.uni-saarland.de"/>
+ <ids type="enumerant" start="6656" end="6719" vendor="Meta" comment="Contact dunfanlu@meta.com"/>
<!-- Enumerants to reserve for future use. To get a block, allocate
multiples of 64 starting at the lowest available point in this
block and add a corresponding <ids> tag immediately above. Make
@@ -201,8 +210,8 @@
<!-- Reserved loop control bits -->
<ids type="LoopControl" start="0" end="15" vendor="Khronos" comment="Reserved LoopControl bits, not available to vendors - see the SPIR-V Specification"/>
- <ids type="LoopControl" start="16" end="25" vendor="Intel" comment="Contact michael.kinsner@intel.com"/>
- <ids type="LoopControl" start="26" end="30" comment="Unreserved bits reservable for use by vendors"/>
+ <ids type="LoopControl" start="16" end="27" vendor="Intel" comment="Contact michael.kinsner@intel.com"/>
+ <ids type="LoopControl" start="28" end="30" comment="Unreserved bits reservable for use by vendors"/>
<ids type="LoopControl" start="31" end="31" vendor="Khronos" comment="Reserved LoopControl bit, not available to vendors"/>
@@ -242,7 +251,8 @@
<!-- Reserved FP fast math mode bits -->
<ids type="FPFastMathMode" start="0" end="15" vendor="Khronos" comment="Reserved FPFastMathMode bits, not available to vendors - see the SPIR-V Specification"/>
<ids type="FPFastMathMode" start="16" end="17" vendor="Intel" comment="Contact michael.kinsner@intel.com"/>
- <ids type="FPFastMathMode" start="18" end="31" comment="Unreserved bits reservable for use by vendors"/>
+ <ids type="FPFastMathMode" start="18" end="18" vendor="khronos" comment="Reserved FPFastMathMode bit, not available to vendors - see SPV_KHR_float_controls2"/>
+ <ids type="FPFastMathMode" start="19" end="31" comment="Unreserved bits reservable for use by vendors"/>
<!-- SECTION: SPIR-V Memory Operand Bit Reservations -->
@@ -261,8 +271,8 @@
<!-- Reserved memory operand bits -->
<ids type="MemoryOperand" start="0" end="15" vendor="Khronos" comment="Reserved MemoryOperand bits, not available to vendors - see the SPIR-V Specification"/>
- <ids type="MemoryOperand" start="16" end="17" vendor="Intel" comment="Contact michael.kinsner@intel.com"/>
- <ids type="MemoryOperand" start="18" end="30" comment="Unreserved bits reservable for use by vendors"/>
+ <ids type="MemoryOperand" start="16" end="18" vendor="Intel" comment="Contact michael.kinsner@intel.com"/>
+ <ids type="MemoryOperand" start="19" end="30" comment="Unreserved bits reservable for use by vendors"/>
<ids type="MemoryOperand" start="31" end="31" vendor="Khronos" comment="Reserved MemoryOperand bit, not available to vendors"/>
<!-- SECTION: SPIR-V Image Operand Bit Reservations -->
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h
index 80165ae5c..e626a7a95 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_gcn_shader.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h
index 8a8bb6ece..563c0b622 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_ballot.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h
index 12b6480f1..e663330c1 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_explicit_vertex_parameter.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h
index 1b14997d2..dd51c5fc8 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/AMD_shader_trinary_minmax.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/DebugInfo.h b/third_party/SPIRV-Headers/include/spirv/unified1/DebugInfo.h
index 4657556bf..a3c0af456 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/DebugInfo.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/DebugInfo.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 The Khronos Group Inc.
+// Copyright (c) 2017-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h b/third_party/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h
index 54cc00e9a..0594f907a 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/GLSL.std.450.h
@@ -1,5 +1,5 @@
/*
-** Copyright (c) 2014-2016 The Khronos Group Inc.
+** Copyright (c) 2014-2024 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h
index 1a3154929..b6c27fa9b 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticClspvReflection.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
@@ -33,7 +33,7 @@ extern "C" {
#endif
enum {
- NonSemanticClspvReflectionRevision = 5,
+ NonSemanticClspvReflectionRevision = 6,
NonSemanticClspvReflectionRevision_BitWidthPadding = 0x7fffffff
};
@@ -78,6 +78,7 @@ enum NonSemanticClspvReflectionInstructions {
NonSemanticClspvReflectionPrintfInfo = 38,
NonSemanticClspvReflectionPrintfBufferStorageBuffer = 39,
NonSemanticClspvReflectionPrintfBufferPointerPushConstant = 40,
+ NonSemanticClspvReflectionNormalizedSamplerMaskPushConstant = 41,
NonSemanticClspvReflectionInstructionsMax = 0x7fffffff
};
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h
index 6ec2b5bb3..8604fe784 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugBreak.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h
index 83796d75e..bc24683ec 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticDebugPrintf.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Khronos Group Inc.
+// Copyright (c) 2020-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h
index c52f32f80..b276b560c 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 The Khronos Group Inc.
+// Copyright (c) 2018-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h
new file mode 100644
index 000000000..331a3d95d
--- /dev/null
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/NonSemanticVkspReflection.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2020-2024 The Khronos Group Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and/or associated documentation files (the
+// "Materials"), to deal in the Materials without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Materials, and to
+// permit persons to whom the Materials are furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Materials.
+//
+// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
+// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
+// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
+// https://www.khronos.org/registry/
+//
+// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+//
+
+#ifndef SPIRV_UNIFIED1_NonSemanticVkspReflection_H_
+#define SPIRV_UNIFIED1_NonSemanticVkspReflection_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ NonSemanticVkspReflectionRevision = 2,
+ NonSemanticVkspReflectionRevision_BitWidthPadding = 0x7fffffff
+};
+
+enum NonSemanticVkspReflectionInstructions {
+ NonSemanticVkspReflectionConfiguration = 1,
+ NonSemanticVkspReflectionStartCounter = 2,
+ NonSemanticVkspReflectionStopCounter = 3,
+ NonSemanticVkspReflectionPushConstants = 4,
+ NonSemanticVkspReflectionSpecializationMapEntry = 5,
+ NonSemanticVkspReflectionDescriptorSetBuffer = 6,
+ NonSemanticVkspReflectionDescriptorSetImage = 7,
+ NonSemanticVkspReflectionDescriptorSetSampler = 8,
+ NonSemanticVkspReflectionInstructionsMax = 0x7fffffff
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_UNIFIED1_NonSemanticVkspReflection_H_
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h b/third_party/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h
index 2745e30df..ed74f203e 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/OpenCL.std.h
@@ -1,5 +1,5 @@
/*
-** Copyright (c) 2015-2019 The Khronos Group Inc.
+** Copyright (c) 2015-2024 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h b/third_party/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h
index e3847c902..ffbd16f1d 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/OpenCLDebugInfo100.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 The Khronos Group Inc.
+// Copyright (c) 2018-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json
index 7d6e8e5b3..918a9e547 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.debuginfo.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2017 The Khronos Group Inc.",
+ "Copyright (c) 2017-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json
index 3d9f39e76..ac8fc6dda 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.glsl.std.450.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2014-2016 The Khronos Group Inc.",
+ "Copyright (c) 2014-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json
index d6499cce1..cfccc80b6 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.clspvreflection.grammar.json
@@ -1,5 +1,5 @@
{
- "revision" : 5,
+ "revision" : 6,
"instructions" : [
{
"opname" : "Kernel",
@@ -395,6 +395,16 @@
{ "kind" : "IdRef", "name" : "Size"},
{ "kind" : "IdRef", "name" : "BufferSize"}
]
+ },
+ {
+ "opname" : "NormalizedSamplerMaskPushConstant",
+ "opcode" : 41,
+ "operands" : [
+ { "kind" : "IdRef", "name" : "Kernel" },
+ { "kind" : "IdRef", "name" : "Ordinal" },
+ { "kind" : "IdRef", "name" : "Offset" },
+ { "kind" : "IdRef", "name" : "Size" }
+ ]
}
],
"operand_kinds" : [
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json
index f3621b0b4..1eb2859a1 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2018 The Khronos Group Inc.",
+ "Copyright (c) 2018-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json
new file mode 100644
index 000000000..379457b9e
--- /dev/null
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json
@@ -0,0 +1,136 @@
+{
+ "revision" : 2,
+ "instructions" : [
+ {
+ "opname" : "Configuration",
+ "opcode" : 1,
+ "operands" : [
+ {"kind" : "LiteralString", "name" : "enabledExtensionNames" },
+ {"kind" : "LiteralInteger", "name" : "specializationInfoDataSize" },
+ {"kind" : "LiteralString", "name" : "specializationInfoData" },
+ {"kind" : "LiteralString", "name" : "shaderName" },
+ {"kind" : "LiteralString", "name" : "EntryPoint" },
+ {"kind" : "LiteralInteger", "name" : "groupCountX" },
+ {"kind" : "LiteralInteger", "name" : "groupCountY" },
+ {"kind" : "LiteralInteger", "name" : "groupCountZ" },
+ {"kind" : "LiteralInteger", "name" : "dispatchId" }
+ ]
+ },
+ {
+ "opname" : "StartCounter",
+ "opcode" : 2,
+ "operands" : [
+ {"kind" : "LiteralString", "name" : "name" }
+ ]
+ },
+ {
+ "opname" : "StopCounter",
+ "opcode" : 3,
+ "operands" : [
+ {"kind" : "IdRef", "name" : "counter" }
+ ]
+ },
+ {
+ "opname" : "PushConstants",
+ "opcode" : 4,
+ "operands" : [
+ { "kind" : "LiteralInteger", "name" : "offset" },
+ { "kind" : "LiteralInteger", "name" : "size" },
+ { "kind" : "LiteralString", "name" : "pValues" },
+ { "kind" : "LiteralInteger", "name" : "stageFlags" }
+ ]
+ },
+ {
+ "opname" : "SpecializationMapEntry",
+ "opcode" : 5,
+ "operands" : [
+ {"kind" : "LiteralInteger", "name" : "constantID" },
+ {"kind" : "LiteralInteger", "name" : "offset" },
+ {"kind" : "LiteralInteger", "name" : "size" }
+ ]
+ },
+ {
+ "opname" : "DescriptorSetBuffer",
+ "opcode" : 6,
+ "operands" : [
+ { "kind" : "LiteralInteger", "name" : "ds" },
+ { "kind" : "LiteralInteger", "name" : "binding" },
+ { "kind" : "LiteralInteger", "name" : "type" },
+ { "kind" : "LiteralInteger", "name" : "flags" },
+ { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount" },
+ { "kind" : "LiteralInteger", "name" : "sharingMode" },
+ { "kind" : "LiteralInteger", "name" : "size" },
+ { "kind" : "LiteralInteger", "name" : "usage" },
+ { "kind" : "LiteralInteger", "name" : "range" },
+ { "kind" : "LiteralInteger", "name" : "offset" },
+ { "kind" : "LiteralInteger", "name" : "memorySize" },
+ { "kind" : "LiteralInteger", "name" : "memoryType" },
+ { "kind" : "LiteralInteger", "name" : "bindOffset" }
+ ]
+ },
+ {
+ "opname" : "DescriptorSetImage",
+ "opcode" : 7,
+ "operands" : [
+ { "kind" : "LiteralInteger", "name" : "ds" },
+ { "kind" : "LiteralInteger", "name" : "binding" },
+ { "kind" : "LiteralInteger", "name" : "type" },
+ { "kind" : "LiteralInteger", "name" : "imageLayout"},
+ { "kind" : "LiteralInteger", "name" : "imageFlags"},
+ { "kind" : "LiteralInteger", "name" : "imageType"},
+ { "kind" : "LiteralInteger", "name" : "imageformat"},
+ { "kind" : "LiteralInteger", "name" : "width"},
+ { "kind" : "LiteralInteger", "name" : "height"},
+ { "kind" : "LiteralInteger", "name" : "depth"},
+ { "kind" : "LiteralInteger", "name" : "mipLevels"},
+ { "kind" : "LiteralInteger", "name" : "arrayLayers"},
+ { "kind" : "LiteralInteger", "name" : "samples"},
+ { "kind" : "LiteralInteger", "name" : "tiling"},
+ { "kind" : "LiteralInteger", "name" : "usage"},
+ { "kind" : "LiteralInteger", "name" : "sharingMode"},
+ { "kind" : "LiteralInteger", "name" : "queueFamilyIndexCount"},
+ { "kind" : "LiteralInteger", "name" : "initialLayout"},
+ { "kind" : "LiteralInteger", "name" : "aspectMask"},
+ { "kind" : "LiteralInteger", "name" : "baseMipLevel"},
+ { "kind" : "LiteralInteger", "name" : "levelCount"},
+ { "kind" : "LiteralInteger", "name" : "baseArrayLayer"},
+ { "kind" : "LiteralInteger", "name" : "layerCount"},
+ { "kind" : "LiteralInteger", "name" : "viewFlags"},
+ { "kind" : "LiteralInteger", "name" : "viewType"},
+ { "kind" : "LiteralInteger", "name" : "viewFormat"},
+ { "kind" : "LiteralInteger", "name" : "component_a"},
+ { "kind" : "LiteralInteger", "name" : "component_b"},
+ { "kind" : "LiteralInteger", "name" : "component_g"},
+ { "kind" : "LiteralInteger", "name" : "component_r"},
+ { "kind" : "LiteralInteger", "name" : "memorySize" },
+ { "kind" : "LiteralInteger", "name" : "memoryType" },
+ { "kind" : "LiteralInteger", "name" : "bindOffset"}
+ ]
+ },
+ {
+ "opname" : "DescriptorSetSampler",
+ "opcode" : 8,
+ "operands" : [
+ { "kind" : "LiteralInteger", "name" : "ds" },
+ { "kind" : "LiteralInteger", "name" : "binding" },
+ { "kind" : "LiteralInteger", "name" : "type" },
+ { "kind" : "LiteralInteger", "name" : "flags"},
+ { "kind" : "LiteralInteger", "name" : "magFilter"},
+ { "kind" : "LiteralInteger", "name" : "minFilter"},
+ { "kind" : "LiteralInteger", "name" : "mipmapMode"},
+ { "kind" : "LiteralInteger", "name" : "addressModeU"},
+ { "kind" : "LiteralInteger", "name" : "addressModeV"},
+ { "kind" : "LiteralInteger", "name" : "addressModeW"},
+ { "kind" : "LiteralFloat", "name" : "mipLodBias"},
+ { "kind" : "LiteralInteger", "name" : "anisotropyEnable"},
+ { "kind" : "LiteralFloat", "name" : "maxAnisotropy"},
+ { "kind" : "LiteralInteger", "name" : "compareEnable"},
+ { "kind" : "LiteralInteger", "name" : "compareOp"},
+ { "kind" : "LiteralFloat", "name" : "minLod"},
+ { "kind" : "LiteralFloat", "name" : "maxLod"},
+ { "kind" : "LiteralInteger", "name" : "borderColor"},
+ { "kind" : "LiteralInteger", "name" : "unnormalizedCoordinates"}
+ ]
+ }
+ ]
+}
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json
index 699fe4036..53b001c53 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.debuginfo.100.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2018 The Khronos Group Inc.",
+ "Copyright (c) 2018-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json
index 4fe45060b..21b7876b0 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/extinst.opencl.std.100.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2014-2016 The Khronos Group Inc.",
+ "Copyright (c) 2014-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.bf b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.bf
index bd12062f6..92b95c876 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.bf
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.bf
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -66,6 +66,11 @@ namespace Spv
HLSL = 5,
CPP_for_OpenCL = 6,
SYCL = 7,
+ HERO_C = 8,
+ NZSL = 9,
+ WGSL = 10,
+ Slang = 11,
+ Zig = 12,
}
[AllowDuplicates, CRepr] public enum ExecutionModel
@@ -165,12 +170,19 @@ namespace Spv
RoundingModeRTZ = 4463,
EarlyAndLateFragmentTestsAMD = 5017,
StencilRefReplacingEXT = 5027,
+ CoalescingAMDX = 5069,
+ MaxNodeRecursionAMDX = 5071,
+ StaticNumWorkgroupsAMDX = 5072,
+ ShaderIndexAMDX = 5073,
+ MaxNumWorkgroupsAMDX = 5077,
StencilRefUnchangedFrontAMD = 5079,
StencilRefGreaterFrontAMD = 5080,
StencilRefLessFrontAMD = 5081,
StencilRefUnchangedBackAMD = 5082,
StencilRefGreaterBackAMD = 5083,
StencilRefLessBackAMD = 5084,
+ QuadDerivativesKHR = 5088,
+ RequireFullQuadsKHR = 5089,
OutputLinesEXT = 5269,
OutputLinesNV = 5269,
OutputPrimitivesEXT = 5270,
@@ -195,9 +207,14 @@ namespace Spv
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
SchedulerTargetFmaxMhzINTEL = 5903,
+ MaximallyReconvergesKHR = 6023,
+ FPFastMathDefault = 6028,
StreamingInterfaceINTEL = 6154,
RegisterMapInterfaceINTEL = 6160,
NamedBarrierCountINTEL = 6417,
+ MaximumRegistersINTEL = 6461,
+ MaximumRegistersIdINTEL = 6462,
+ NamedMaximumRegistersINTEL = 6463,
}
[AllowDuplicates, CRepr] public enum StorageClass
@@ -216,6 +233,8 @@ namespace Spv
Image = 11,
StorageBuffer = 12,
TileImageEXT = 4172,
+ NodePayloadAMDX = 5068,
+ NodeOutputPayloadAMDX = 5076,
CallableDataKHR = 5328,
CallableDataNV = 5328,
IncomingCallableDataKHR = 5329,
@@ -353,6 +372,8 @@ namespace Spv
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
+ UnsignedIntRaw10EXT = 19,
+ UnsignedIntRaw12EXT = 20,
}
[AllowDuplicates, CRepr] public enum ImageOperandsShift
@@ -411,8 +432,11 @@ namespace Spv
NSZ = 2,
AllowRecip = 3,
Fast = 4,
+ AllowContract = 16,
AllowContractFastINTEL = 16,
+ AllowReassoc = 17,
AllowReassocINTEL = 17,
+ AllowTransform = 18,
}
[AllowDuplicates, CRepr] public enum FPFastMathModeMask
@@ -423,8 +447,11 @@ namespace Spv
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
+ AllowContract = 0x00010000,
AllowContractFastINTEL = 0x00010000,
+ AllowReassoc = 0x00020000,
AllowReassocINTEL = 0x00020000,
+ AllowTransform = 0x00040000,
}
[AllowDuplicates, CRepr] public enum FPRoundingMode
@@ -515,7 +542,12 @@ namespace Spv
NoUnsignedWrap = 4470,
WeightTextureQCOM = 4487,
BlockMatchTextureQCOM = 4488,
+ BlockMatchSamplerQCOM = 4499,
ExplicitInterpAMD = 4999,
+ NodeSharesPayloadLimitsWithAMDX = 5019,
+ NodeMaxPayloadsAMDX = 5020,
+ TrackFinishWritingAMDX = 5078,
+ PayloadNodeNameAMDX = 5091,
OverrideCoverageNV = 5248,
PassthroughNV = 5250,
ViewportRelativeNV = 5252,
@@ -565,6 +597,9 @@ namespace Spv
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ StridesizeINTEL = 5883,
+ WordsizeINTEL = 5884,
+ TrueDualPortINTEL = 5885,
BurstCoalesceINTEL = 5899,
CacheSizeINTEL = 5900,
DontStaticallyCoalesceINTEL = 5901,
@@ -583,6 +618,8 @@ namespace Spv
SingleElementVectorINTEL = 6085,
VectorComputeCallableFunctionINTEL = 6087,
MediaBlockIOINTEL = 6140,
+ StallFreeINTEL = 6151,
+ FPMaxErrorDecorationINTEL = 6170,
LatencyControlLabelINTEL = 6172,
LatencyControlConstraintINTEL = 6173,
ConduitKernelArgumentINTEL = 6175,
@@ -594,6 +631,11 @@ namespace Spv
MMHostInterfaceMaxBurstINTEL = 6181,
MMHostInterfaceWaitRequestINTEL = 6182,
StableKernelArgumentINTEL = 6183,
+ HostAccessINTEL = 6188,
+ InitModeINTEL = 6190,
+ ImplementInRegisterMapINTEL = 6191,
+ CacheControlLoadINTEL = 6442,
+ CacheControlStoreINTEL = 6443,
}
[AllowDuplicates, CRepr] public enum BuiltIn
@@ -669,6 +711,8 @@ namespace Spv
BaryCoordSmoothSampleAMD = 4997,
BaryCoordPullModelAMD = 4998,
FragStencilRefEXT = 5014,
+ CoalescedInputCountAMDX = 5021,
+ ShaderIndexAMDX = 5073,
ViewportMaskNV = 5253,
SecondaryPositionNV = 5257,
SecondaryViewportMaskNV = 5258,
@@ -722,6 +766,8 @@ namespace Spv
HitKindNV = 5333,
CurrentRayTimeNV = 5334,
HitTriangleVertexPositionsKHR = 5335,
+ HitMicroTriangleVertexPositionsNV = 5337,
+ HitMicroTriangleVertexBarycentricsNV = 5344,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -729,6 +775,8 @@ namespace Spv
SMCountNV = 5375,
WarpIDNV = 5376,
SMIDNV = 5377,
+ HitKindFrontFacingMicroTriangleNV = 5405,
+ HitKindBackFacingMicroTriangleNV = 5406,
CullMaskKHR = 6021,
}
@@ -1036,6 +1084,7 @@ namespace Spv
TextureSampleWeightedQCOM = 4484,
TextureBoxFilterQCOM = 4485,
TextureBlockMatchQCOM = 4486,
+ TextureBlockMatch2QCOM = 4498,
Float16ImageAMD = 5008,
ImageGatherBiasLodAMD = 5009,
FragmentMaskAMD = 5010,
@@ -1043,6 +1092,8 @@ namespace Spv
ImageReadWriteLodAMD = 5015,
Int64ImageEXT = 5016,
ShaderClockKHR = 5055,
+ ShaderEnqueueAMDX = 5067,
+ QuadControlKHR = 5087,
SampleMaskOverrideCoverageNV = 5249,
GeometryShaderPassthroughNV = 5251,
ShaderViewportIndexLayerEXT = 5254,
@@ -1102,10 +1153,14 @@ namespace Spv
FragmentShaderPixelInterlockEXT = 5378,
DemoteToHelperInvocation = 5379,
DemoteToHelperInvocationEXT = 5379,
+ DisplacementMicromapNV = 5380,
RayTracingOpacityMicromapEXT = 5381,
ShaderInvocationReorderNV = 5383,
BindlessTextureNV = 5390,
RayQueryPositionFetchKHR = 5391,
+ AtomicFloat16VectorNV = 5404,
+ RayTracingDisplacementMicromapNV = 5409,
+ RawAccessChainsNV = 5414,
SubgroupShuffleINTEL = 5568,
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
@@ -1157,20 +1212,29 @@ namespace Spv
DotProduct = 6019,
DotProductKHR = 6019,
RayCullMaskKHR = 6020,
+ CooperativeMatrixKHR = 6022,
BitInstructions = 6025,
GroupNonUniformRotateKHR = 6026,
+ FloatControls2 = 6029,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
- LongConstantCompositeINTEL = 6089,
+ LongCompositesINTEL = 6089,
OptNoneINTEL = 6094,
AtomicFloat16AddEXT = 6095,
DebugInfoModuleINTEL = 6114,
BFloat16ConversionINTEL = 6115,
SplitBarrierINTEL = 6141,
+ FPGAClusterAttributesV2INTEL = 6150,
FPGAKernelAttributesv2INTEL = 6161,
+ FPMaxErrorINTEL = 6169,
FPGALatencyControlINTEL = 6171,
FPGAArgumentInterfacesINTEL = 6174,
+ GlobalVariableHostAccessINTEL = 6187,
+ GlobalVariableFPGADecorationsINTEL = 6189,
GroupUniformArithmeticKHR = 6400,
+ MaskedGatherScatterINTEL = 6427,
+ CacheControlsINTEL = 6441,
+ RegisterLimitsINTEL = 6460,
}
[AllowDuplicates, CRepr] public enum RayFlagsShift
@@ -1278,6 +1342,87 @@ namespace Spv
PackedVectorFormat4x8BitKHR = 0,
}
+ [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsShift
+ {
+ MatrixASignedComponentsKHR = 0,
+ MatrixBSignedComponentsKHR = 1,
+ MatrixCSignedComponentsKHR = 2,
+ MatrixResultSignedComponentsKHR = 3,
+ SaturatingAccumulationKHR = 4,
+ }
+
+ [AllowDuplicates, CRepr] public enum CooperativeMatrixOperandsMask
+ {
+ MaskNone = 0,
+ MatrixASignedComponentsKHR = 0x00000001,
+ MatrixBSignedComponentsKHR = 0x00000002,
+ MatrixCSignedComponentsKHR = 0x00000004,
+ MatrixResultSignedComponentsKHR = 0x00000008,
+ SaturatingAccumulationKHR = 0x00000010,
+ }
+
+ [AllowDuplicates, CRepr] public enum CooperativeMatrixLayout
+ {
+ RowMajorKHR = 0,
+ ColumnMajorKHR = 1,
+ }
+
+ [AllowDuplicates, CRepr] public enum CooperativeMatrixUse
+ {
+ MatrixAKHR = 0,
+ MatrixBKHR = 1,
+ MatrixAccumulatorKHR = 2,
+ }
+
+ [AllowDuplicates, CRepr] public enum InitializationModeQualifier
+ {
+ InitOnDeviceReprogramINTEL = 0,
+ InitOnDeviceResetINTEL = 1,
+ }
+
+ [AllowDuplicates, CRepr] public enum HostAccessQualifier
+ {
+ NoneINTEL = 0,
+ ReadINTEL = 1,
+ WriteINTEL = 2,
+ ReadWriteINTEL = 3,
+ }
+
+ [AllowDuplicates, CRepr] public enum LoadCacheControl
+ {
+ UncachedINTEL = 0,
+ CachedINTEL = 1,
+ StreamingINTEL = 2,
+ InvalidateAfterReadINTEL = 3,
+ ConstCachedINTEL = 4,
+ }
+
+ [AllowDuplicates, CRepr] public enum StoreCacheControl
+ {
+ UncachedINTEL = 0,
+ WriteThroughINTEL = 1,
+ WriteBackINTEL = 2,
+ StreamingINTEL = 3,
+ }
+
+ [AllowDuplicates, CRepr] public enum NamedMaximumNumberOfRegisters
+ {
+ AutoINTEL = 0,
+ }
+
+ [AllowDuplicates, CRepr] public enum RawAccessChainOperandsShift
+ {
+ RobustnessPerComponentNV = 0,
+ RobustnessPerElementNV = 1,
+ }
+
+ [AllowDuplicates, CRepr] public enum RawAccessChainOperandsMask
+ {
+ MaskNone = 0,
+ RobustnessPerComponentNV = 0x00000001,
+ RobustnessPerElementNV = 0x00000002,
+ }
+
[AllowDuplicates, CRepr] public enum Op
{
OpNop = 0,
@@ -1652,6 +1797,11 @@ namespace Spv
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1663,6 +1813,10 @@ namespace Spv
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1674,6 +1828,11 @@ namespace Spv
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1712,6 +1871,8 @@ namespace Spv
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1740,6 +1901,7 @@ namespace Spv
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1981,6 +2143,7 @@ namespace Spv
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1993,6 +2156,8 @@ namespace Spv
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
}
}
}
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json
index 377e2ec08..5d904cae1 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.core.grammar.json
@@ -1,6 +1,6 @@
{
"copyright" : [
- "Copyright (c) 2014-2020 The Khronos Group Inc.",
+ "Copyright (c) 2014-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
@@ -137,7 +137,8 @@
{
"opname" : "OpNop",
"class" : "Miscellaneous",
- "opcode" : 0
+ "opcode" : 0,
+ "version" : "1.0"
},
{
"opname" : "OpUndef",
@@ -146,7 +147,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version" : "1.0"
},
{
"opname" : "OpSourceContinued",
@@ -154,7 +156,8 @@
"opcode" : 2,
"operands" : [
{ "kind" : "LiteralString", "name" : "'Continued Source'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSource",
@@ -165,7 +168,8 @@
{ "kind" : "LiteralInteger", "name" : "'Version'" },
{ "kind" : "IdRef", "quantifier" : "?", "name" : "'File'" },
{ "kind" : "LiteralString", "quantifier" : "?", "name" : "'Source'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSourceExtension",
@@ -173,7 +177,8 @@
"opcode" : 4,
"operands" : [
{ "kind" : "LiteralString", "name" : "'Extension'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpName",
@@ -182,7 +187,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Target'" },
{ "kind" : "LiteralString", "name" : "'Name'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpMemberName",
@@ -192,7 +198,8 @@
{ "kind" : "IdRef", "name" : "'Type'" },
{ "kind" : "LiteralInteger", "name" : "'Member'" },
{ "kind" : "LiteralString", "name" : "'Name'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpString",
@@ -201,7 +208,8 @@
"operands" : [
{ "kind" : "IdResult" },
{ "kind" : "LiteralString", "name" : "'String'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLine",
@@ -211,7 +219,8 @@
{ "kind" : "IdRef", "name" : "'File'" },
{ "kind" : "LiteralInteger", "name" : "'Line'" },
{ "kind" : "LiteralInteger", "name" : "'Column'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpExtension",
@@ -219,7 +228,8 @@
"opcode" : 10,
"operands" : [
{ "kind" : "LiteralString", "name" : "'Name'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpExtInstImport",
@@ -228,7 +238,8 @@
"operands" : [
{ "kind" : "IdResult" },
{ "kind" : "LiteralString", "name" : "'Name'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpExtInst",
@@ -240,7 +251,8 @@
{ "kind" : "IdRef", "name" : "'Set'" },
{ "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpMemoryModel",
@@ -249,7 +261,8 @@
"operands" : [
{ "kind" : "AddressingModel" },
{ "kind" : "MemoryModel" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpEntryPoint",
@@ -260,7 +273,8 @@
{ "kind" : "IdRef", "name" : "'Entry Point'" },
{ "kind" : "LiteralString", "name" : "'Name'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpExecutionMode",
@@ -269,7 +283,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Entry Point'" },
{ "kind" : "ExecutionMode", "name" : "'Mode'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCapability",
@@ -277,7 +292,8 @@
"opcode" : 17,
"operands" : [
{ "kind" : "Capability", "name" : "'Capability'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeVoid",
@@ -285,7 +301,8 @@
"opcode" : 19,
"operands" : [
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeBool",
@@ -293,7 +310,8 @@
"opcode" : 20,
"operands" : [
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeInt",
@@ -303,7 +321,8 @@
{ "kind" : "IdResult" },
{ "kind" : "LiteralInteger", "name" : "'Width'" },
{ "kind" : "LiteralInteger", "name" : "'Signedness'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeFloat",
@@ -312,7 +331,8 @@
"operands" : [
{ "kind" : "IdResult" },
{ "kind" : "LiteralInteger", "name" : "'Width'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeVector",
@@ -322,7 +342,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Component Type'" },
{ "kind" : "LiteralInteger", "name" : "'Component Count'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeMatrix",
@@ -333,7 +354,8 @@
{ "kind" : "IdRef", "name" : "'Column Type'" },
{ "kind" : "LiteralInteger", "name" : "'Column Count'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeImage",
@@ -349,7 +371,8 @@
{ "kind" : "LiteralInteger", "name" : "'Sampled'" },
{ "kind" : "ImageFormat" },
{ "kind" : "AccessQualifier", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeSampler",
@@ -357,7 +380,8 @@
"opcode" : 26,
"operands" : [
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeSampledImage",
@@ -366,7 +390,8 @@
"operands" : [
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image Type'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeArray",
@@ -376,7 +401,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Element Type'" },
{ "kind" : "IdRef", "name" : "'Length'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeRuntimeArray",
@@ -386,7 +412,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Element Type'" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeStruct",
@@ -395,7 +422,8 @@
"operands" : [
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeOpaque",
@@ -405,7 +433,8 @@
{ "kind" : "IdResult" },
{ "kind" : "LiteralString", "name" : "The name of the opaque type." }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpTypePointer",
@@ -415,7 +444,8 @@
{ "kind" : "IdResult" },
{ "kind" : "StorageClass" },
{ "kind" : "IdRef", "name" : "'Type'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeFunction",
@@ -425,7 +455,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Return Type'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..." }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTypeEvent",
@@ -434,7 +465,8 @@
"operands" : [
{ "kind" : "IdResult" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeDeviceEvent",
@@ -443,7 +475,8 @@
"operands" : [
{ "kind" : "IdResult" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeReserveId",
@@ -452,7 +485,8 @@
"operands" : [
{ "kind" : "IdResult" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeQueue",
@@ -461,7 +495,8 @@
"operands" : [
{ "kind" : "IdResult" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpTypePipe",
@@ -471,7 +506,8 @@
{ "kind" : "IdResult" },
{ "kind" : "AccessQualifier", "name" : "'Qualifier'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpTypeForwardPointer",
@@ -484,7 +520,8 @@
"capabilities" : [
"Addresses",
"PhysicalStorageBufferAddresses"
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConstantTrue",
@@ -493,7 +530,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConstantFalse",
@@ -502,7 +540,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConstant",
@@ -512,7 +551,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "LiteralContextDependentNumber", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConstantComposite",
@@ -522,7 +562,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConstantSampler",
@@ -535,7 +576,8 @@
{ "kind" : "LiteralInteger", "name" : "'Param'" },
{ "kind" : "SamplerFilterMode" }
],
- "capabilities" : [ "LiteralSampler" ]
+ "capabilities" : [ "LiteralSampler" ],
+ "version": "1.0"
},
{
"opname" : "OpConstantNull",
@@ -544,7 +586,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSpecConstantTrue",
@@ -553,7 +596,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSpecConstantFalse",
@@ -562,7 +606,8 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSpecConstant",
@@ -572,7 +617,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "LiteralContextDependentNumber", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSpecConstantComposite",
@@ -582,7 +628,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSpecConstantOp",
@@ -592,7 +639,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "LiteralSpecConstantOpInteger", "name" : "'Opcode'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFunction",
@@ -603,7 +651,8 @@
{ "kind" : "IdResult" },
{ "kind" : "FunctionControl" },
{ "kind" : "IdRef", "name" : "'Function Type'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFunctionParameter",
@@ -612,12 +661,14 @@
"operands" : [
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFunctionEnd",
"class" : "Function",
- "opcode" : 56
+ "opcode" : 56,
+ "version" : "1.0"
},
{
"opname" : "OpFunctionCall",
@@ -628,7 +679,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Function'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Argument 0', +\n'Argument 1', +\n..." }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpVariable",
@@ -639,7 +691,8 @@
{ "kind" : "IdResult" },
{ "kind" : "StorageClass" },
{ "kind" : "IdRef", "quantifier" : "?", "name" : "'Initializer'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageTexelPointer",
@@ -651,7 +704,8 @@
{ "kind" : "IdRef", "name" : "'Image'" },
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "IdRef", "name" : "'Sample'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLoad",
@@ -662,7 +716,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "MemoryAccess", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpStore",
@@ -672,7 +727,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "IdRef", "name" : "'Object'" },
{ "kind" : "MemoryAccess", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCopyMemory",
@@ -683,7 +739,8 @@
{ "kind" : "IdRef", "name" : "'Source'" },
{ "kind" : "MemoryAccess", "quantifier" : "?" },
{ "kind" : "MemoryAccess", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCopyMemorySized",
@@ -696,7 +753,8 @@
{ "kind" : "MemoryAccess", "quantifier" : "?" },
{ "kind" : "MemoryAccess", "quantifier" : "?" }
],
- "capabilities" : [ "Addresses" ]
+ "capabilities" : [ "Addresses" ],
+ "version": "1.0"
},
{
"opname" : "OpAccessChain",
@@ -707,7 +765,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpInBoundsAccessChain",
@@ -718,7 +777,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpPtrAccessChain",
@@ -736,7 +796,8 @@
"VariablePointers",
"VariablePointersStorageBuffer",
"PhysicalStorageBufferAddresses"
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpArrayLength",
@@ -748,7 +809,8 @@
{ "kind" : "IdRef", "name" : "'Structure'" },
{ "kind" : "LiteralInteger", "name" : "'Array member'" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpGenericPtrMemSemantics",
@@ -759,7 +821,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Pointer'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpInBoundsPtrAccessChain",
@@ -772,7 +835,8 @@
{ "kind" : "IdRef", "name" : "'Element'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Indexes'" }
],
- "capabilities" : [ "Addresses" ]
+ "capabilities" : [ "Addresses" ],
+ "version": "1.0"
},
{
"opname" : "OpDecorate",
@@ -781,7 +845,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Target'" },
{ "kind" : "Decoration" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpMemberDecorate",
@@ -791,7 +856,8 @@
{ "kind" : "IdRef", "name" : "'Structure Type'" },
{ "kind" : "LiteralInteger", "name" : "'Member'" },
{ "kind" : "Decoration" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpDecorationGroup",
@@ -799,7 +865,8 @@
"opcode" : 73,
"operands" : [
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpGroupDecorate",
@@ -808,7 +875,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Decoration Group'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Targets'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpGroupMemberDecorate",
@@ -817,7 +885,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Decoration Group'" },
{ "kind" : "PairIdRefLiteralInteger", "quantifier" : "*", "name" : "'Targets'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpVectorExtractDynamic",
@@ -828,7 +897,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Vector'" },
{ "kind" : "IdRef", "name" : "'Index'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpVectorInsertDynamic",
@@ -840,7 +910,8 @@
{ "kind" : "IdRef", "name" : "'Vector'" },
{ "kind" : "IdRef", "name" : "'Component'" },
{ "kind" : "IdRef", "name" : "'Index'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpVectorShuffle",
@@ -852,7 +923,8 @@
{ "kind" : "IdRef", "name" : "'Vector 1'" },
{ "kind" : "IdRef", "name" : "'Vector 2'" },
{ "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Components'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCompositeConstruct",
@@ -862,7 +934,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCompositeExtract",
@@ -873,7 +946,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Composite'" },
{ "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCompositeInsert",
@@ -885,7 +959,8 @@
{ "kind" : "IdRef", "name" : "'Object'" },
{ "kind" : "IdRef", "name" : "'Composite'" },
{ "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Indexes'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpCopyObject",
@@ -895,7 +970,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpTranspose",
@@ -906,7 +982,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Matrix'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpSampledImage",
@@ -917,7 +994,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" },
{ "kind" : "IdRef", "name" : "'Sampler'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleImplicitLod",
@@ -930,7 +1008,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleExplicitLod",
@@ -942,7 +1021,8 @@
{ "kind" : "IdRef", "name" : "'Sampled Image'" },
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleDrefImplicitLod",
@@ -956,7 +1036,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleDrefExplicitLod",
@@ -970,7 +1051,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleProjImplicitLod",
@@ -983,7 +1065,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleProjExplicitLod",
@@ -996,7 +1079,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleProjDrefImplicitLod",
@@ -1010,7 +1094,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSampleProjDrefExplicitLod",
@@ -1024,7 +1109,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageFetch",
@@ -1036,7 +1122,8 @@
{ "kind" : "IdRef", "name" : "'Image'" },
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageGather",
@@ -1050,7 +1137,8 @@
{ "kind" : "IdRef", "name" : "'Component'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageDrefGather",
@@ -1064,7 +1152,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpImageRead",
@@ -1076,7 +1165,8 @@
{ "kind" : "IdRef", "name" : "'Image'" },
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageWrite",
@@ -1087,7 +1177,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "IdRef", "name" : "'Texel'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImage",
@@ -1097,7 +1188,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Sampled Image'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpImageQueryFormat",
@@ -1108,7 +1200,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQueryOrder",
@@ -1119,7 +1212,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQuerySizeLod",
@@ -1131,7 +1225,8 @@
{ "kind" : "IdRef", "name" : "'Image'" },
{ "kind" : "IdRef", "name" : "'Level of Detail'" }
],
- "capabilities" : [ "Kernel", "ImageQuery" ]
+ "capabilities" : [ "Kernel", "ImageQuery" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQuerySize",
@@ -1142,7 +1237,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" }
],
- "capabilities" : [ "Kernel", "ImageQuery" ]
+ "capabilities" : [ "Kernel", "ImageQuery" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQueryLod",
@@ -1154,7 +1250,8 @@
{ "kind" : "IdRef", "name" : "'Sampled Image'" },
{ "kind" : "IdRef", "name" : "'Coordinate'" }
],
- "capabilities" : [ "ImageQuery" ]
+ "capabilities" : [ "ImageQuery" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQueryLevels",
@@ -1165,7 +1262,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" }
],
- "capabilities" : [ "Kernel", "ImageQuery" ]
+ "capabilities" : [ "Kernel", "ImageQuery" ],
+ "version": "1.0"
},
{
"opname" : "OpImageQuerySamples",
@@ -1176,7 +1274,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Image'" }
],
- "capabilities" : [ "Kernel", "ImageQuery" ]
+ "capabilities" : [ "Kernel", "ImageQuery" ],
+ "version": "1.0"
},
{
"opname" : "OpConvertFToU",
@@ -1186,7 +1285,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Float Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConvertFToS",
@@ -1196,7 +1296,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Float Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConvertSToF",
@@ -1206,7 +1307,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Signed Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConvertUToF",
@@ -1216,7 +1318,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Unsigned Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUConvert",
@@ -1226,7 +1329,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Unsigned Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSConvert",
@@ -1236,7 +1340,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Signed Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFConvert",
@@ -1246,7 +1351,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Float Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpQuantizeToF16",
@@ -1256,7 +1362,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpConvertPtrToU",
@@ -1270,7 +1377,8 @@
"capabilities" : [
"Addresses",
"PhysicalStorageBufferAddresses"
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSatConvertSToU",
@@ -1281,7 +1389,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Signed Value'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpSatConvertUToS",
@@ -1292,7 +1401,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Unsigned Value'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpConvertUToPtr",
@@ -1306,7 +1416,8 @@
"capabilities" : [
"Addresses",
"PhysicalStorageBufferAddresses"
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpPtrCastToGeneric",
@@ -1317,7 +1428,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Pointer'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpGenericCastToPtr",
@@ -1328,7 +1440,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Pointer'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpGenericCastToPtrExplicit",
@@ -1340,7 +1453,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "StorageClass", "name" : "'Storage'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpBitcast",
@@ -1350,7 +1464,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSNegate",
@@ -1360,7 +1475,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFNegate",
@@ -1370,7 +1486,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIAdd",
@@ -1381,7 +1498,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFAdd",
@@ -1392,7 +1510,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpISub",
@@ -1403,7 +1522,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFSub",
@@ -1414,7 +1534,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIMul",
@@ -1425,7 +1546,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFMul",
@@ -1436,7 +1558,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUDiv",
@@ -1447,7 +1570,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSDiv",
@@ -1458,7 +1582,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFDiv",
@@ -1469,7 +1594,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUMod",
@@ -1480,7 +1606,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSRem",
@@ -1491,7 +1618,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSMod",
@@ -1502,7 +1630,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFRem",
@@ -1513,7 +1642,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFMod",
@@ -1524,7 +1654,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpVectorTimesScalar",
@@ -1535,7 +1666,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Vector'" },
{ "kind" : "IdRef", "name" : "'Scalar'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpMatrixTimesScalar",
@@ -1547,7 +1679,8 @@
{ "kind" : "IdRef", "name" : "'Matrix'" },
{ "kind" : "IdRef", "name" : "'Scalar'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpVectorTimesMatrix",
@@ -1559,7 +1692,8 @@
{ "kind" : "IdRef", "name" : "'Vector'" },
{ "kind" : "IdRef", "name" : "'Matrix'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpMatrixTimesVector",
@@ -1571,7 +1705,8 @@
{ "kind" : "IdRef", "name" : "'Matrix'" },
{ "kind" : "IdRef", "name" : "'Vector'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpMatrixTimesMatrix",
@@ -1583,7 +1718,8 @@
{ "kind" : "IdRef", "name" : "'LeftMatrix'" },
{ "kind" : "IdRef", "name" : "'RightMatrix'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpOuterProduct",
@@ -1595,7 +1731,8 @@
{ "kind" : "IdRef", "name" : "'Vector 1'" },
{ "kind" : "IdRef", "name" : "'Vector 2'" }
],
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"opname" : "OpDot",
@@ -1606,7 +1743,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Vector 1'" },
{ "kind" : "IdRef", "name" : "'Vector 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIAddCarry",
@@ -1617,7 +1755,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpISubBorrow",
@@ -1628,7 +1767,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUMulExtended",
@@ -1639,7 +1779,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSMulExtended",
@@ -1650,7 +1791,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAny",
@@ -1660,7 +1802,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Vector'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAll",
@@ -1670,7 +1813,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Vector'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIsNan",
@@ -1680,7 +1824,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'x'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIsInf",
@@ -1690,7 +1835,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'x'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIsFinite",
@@ -1701,7 +1847,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'x'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpIsNormal",
@@ -1712,7 +1859,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'x'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpSignBitSet",
@@ -1723,7 +1871,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'x'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpLessOrGreater",
@@ -1736,6 +1885,7 @@
{ "kind" : "IdRef", "name" : "'y'" }
],
"capabilities" : [ "Kernel" ],
+ "version" : "1.0",
"lastVersion" : "1.5"
},
{
@@ -1748,7 +1898,8 @@
{ "kind" : "IdRef", "name" : "'x'" },
{ "kind" : "IdRef", "name" : "'y'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpUnordered",
@@ -1760,7 +1911,8 @@
{ "kind" : "IdRef", "name" : "'x'" },
{ "kind" : "IdRef", "name" : "'y'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpLogicalEqual",
@@ -1771,7 +1923,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLogicalNotEqual",
@@ -1782,7 +1935,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLogicalOr",
@@ -1793,7 +1947,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLogicalAnd",
@@ -1804,7 +1959,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version" : "1.0"
},
{
"opname" : "OpLogicalNot",
@@ -1814,7 +1970,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSelect",
@@ -1826,7 +1983,8 @@
{ "kind" : "IdRef", "name" : "'Condition'" },
{ "kind" : "IdRef", "name" : "'Object 1'" },
{ "kind" : "IdRef", "name" : "'Object 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpIEqual",
@@ -1837,7 +1995,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpINotEqual",
@@ -1848,7 +2007,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUGreaterThan",
@@ -1859,7 +2019,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSGreaterThan",
@@ -1870,7 +2031,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUGreaterThanEqual",
@@ -1881,7 +2043,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSGreaterThanEqual",
@@ -1892,7 +2055,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpULessThan",
@@ -1903,7 +2067,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSLessThan",
@@ -1914,7 +2079,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpULessThanEqual",
@@ -1925,7 +2091,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSLessThanEqual",
@@ -1936,7 +2103,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdEqual",
@@ -1947,7 +2115,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordEqual",
@@ -1958,7 +2127,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdNotEqual",
@@ -1969,7 +2139,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordNotEqual",
@@ -1980,7 +2151,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdLessThan",
@@ -1991,7 +2163,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordLessThan",
@@ -2002,7 +2175,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdGreaterThan",
@@ -2013,7 +2187,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordGreaterThan",
@@ -2024,7 +2199,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdLessThanEqual",
@@ -2035,7 +2211,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordLessThanEqual",
@@ -2046,7 +2223,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFOrdGreaterThanEqual",
@@ -2057,7 +2235,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpFUnordGreaterThanEqual",
@@ -2068,7 +2247,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpShiftRightLogical",
@@ -2079,7 +2259,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" },
{ "kind" : "IdRef", "name" : "'Shift'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpShiftRightArithmetic",
@@ -2090,7 +2271,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" },
{ "kind" : "IdRef", "name" : "'Shift'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpShiftLeftLogical",
@@ -2101,7 +2283,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" },
{ "kind" : "IdRef", "name" : "'Shift'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBitwiseOr",
@@ -2112,7 +2295,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBitwiseXor",
@@ -2123,7 +2307,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBitwiseAnd",
@@ -2134,7 +2319,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand 1'" },
{ "kind" : "IdRef", "name" : "'Operand 2'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpNot",
@@ -2144,7 +2330,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Operand'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBitFieldInsert",
@@ -2158,7 +2345,8 @@
{ "kind" : "IdRef", "name" : "'Offset'" },
{ "kind" : "IdRef", "name" : "'Count'" }
],
- "capabilities" : [ "Shader", "BitInstructions" ]
+ "capabilities" : [ "Shader", "BitInstructions" ],
+ "version": "1.0"
},
{
"opname" : "OpBitFieldSExtract",
@@ -2171,7 +2359,8 @@
{ "kind" : "IdRef", "name" : "'Offset'" },
{ "kind" : "IdRef", "name" : "'Count'" }
],
- "capabilities" : [ "Shader", "BitInstructions" ]
+ "capabilities" : [ "Shader", "BitInstructions" ],
+ "version": "1.0"
},
{
"opname" : "OpBitFieldUExtract",
@@ -2184,7 +2373,8 @@
{ "kind" : "IdRef", "name" : "'Offset'" },
{ "kind" : "IdRef", "name" : "'Count'" }
],
- "capabilities" : [ "Shader", "BitInstructions" ]
+ "capabilities" : [ "Shader", "BitInstructions" ],
+ "version": "1.0"
},
{
"opname" : "OpBitReverse",
@@ -2195,7 +2385,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" }
],
- "capabilities" : [ "Shader", "BitInstructions" ]
+ "capabilities" : [ "Shader", "BitInstructions" ],
+ "version": "1.0"
},
{
"opname" : "OpBitCount",
@@ -2205,7 +2396,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Base'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpDPdx",
@@ -2216,7 +2408,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpDPdy",
@@ -2227,7 +2420,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpFwidth",
@@ -2238,7 +2432,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpDPdxFine",
@@ -2249,7 +2444,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpDPdyFine",
@@ -2260,7 +2456,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpFwidthFine",
@@ -2271,7 +2468,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpDPdxCoarse",
@@ -2282,7 +2480,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpDPdyCoarse",
@@ -2293,7 +2492,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpFwidthCoarse",
@@ -2304,19 +2504,22 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'P'" }
],
- "capabilities" : [ "DerivativeControl" ]
+ "capabilities" : [ "DerivativeControl" ],
+ "version": "1.0"
},
{
"opname" : "OpEmitVertex",
"class" : "Primitive",
"opcode" : 218,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"opname" : "OpEndPrimitive",
"class" : "Primitive",
"opcode" : 219,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"opname" : "OpEmitStreamVertex",
@@ -2325,7 +2528,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Stream'" }
],
- "capabilities" : [ "GeometryStreams" ]
+ "capabilities" : [ "GeometryStreams" ],
+ "version": "1.0"
},
{
"opname" : "OpEndStreamPrimitive",
@@ -2334,7 +2538,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Stream'" }
],
- "capabilities" : [ "GeometryStreams" ]
+ "capabilities" : [ "GeometryStreams" ],
+ "version": "1.0"
},
{
"opname" : "OpControlBarrier",
@@ -2344,7 +2549,8 @@
{ "kind" : "IdScope", "name" : "'Execution'" },
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpMemoryBarrier",
@@ -2353,7 +2559,8 @@
"operands" : [
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicLoad",
@@ -2365,7 +2572,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicStore",
@@ -2376,7 +2584,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicExchange",
@@ -2389,7 +2598,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicCompareExchange",
@@ -2404,7 +2614,8 @@
{ "kind" : "IdMemorySemantics", "name" : "'Unequal'" },
{ "kind" : "IdRef", "name" : "'Value'" },
{ "kind" : "IdRef", "name" : "'Comparator'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicCompareExchangeWeak",
@@ -2421,6 +2632,7 @@
{ "kind" : "IdRef", "name" : "'Comparator'" }
],
"capabilities" : [ "Kernel" ],
+ "version" : "1.0",
"lastVersion" : "1.3"
},
{
@@ -2433,7 +2645,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicIDecrement",
@@ -2445,7 +2658,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicIAdd",
@@ -2458,7 +2672,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicISub",
@@ -2471,7 +2686,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicSMin",
@@ -2484,7 +2700,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicUMin",
@@ -2497,7 +2714,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicSMax",
@@ -2510,7 +2728,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicUMax",
@@ -2523,7 +2742,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicAnd",
@@ -2536,7 +2756,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicOr",
@@ -2549,7 +2770,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicXor",
@@ -2562,7 +2784,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpPhi",
@@ -2572,7 +2795,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" },
{ "kind" : "PairIdRefIdRef", "quantifier" : "*", "name" : "'Variable, Parent, ...'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLoopMerge",
@@ -2582,7 +2806,8 @@
{ "kind" : "IdRef", "name" : "'Merge Block'" },
{ "kind" : "IdRef", "name" : "'Continue Target'" },
{ "kind" : "LoopControl" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSelectionMerge",
@@ -2591,7 +2816,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Merge Block'" },
{ "kind" : "SelectionControl" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpLabel",
@@ -2599,7 +2825,8 @@
"opcode" : 248,
"operands" : [
{ "kind" : "IdResult" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBranch",
@@ -2607,7 +2834,8 @@
"opcode" : 249,
"operands" : [
{ "kind" : "IdRef", "name" : "'Target Label'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpBranchConditional",
@@ -2618,7 +2846,8 @@
{ "kind" : "IdRef", "name" : "'True Label'" },
{ "kind" : "IdRef", "name" : "'False Label'" },
{ "kind" : "LiteralInteger", "quantifier" : "*", "name" : "'Branch weights'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpSwitch",
@@ -2628,18 +2857,21 @@
{ "kind" : "IdRef", "name" : "'Selector'" },
{ "kind" : "IdRef", "name" : "'Default'" },
{ "kind" : "PairLiteralIntegerIdRef", "quantifier" : "*", "name" : "'Target'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpKill",
"class" : "Control-Flow",
"opcode" : 252,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"opname" : "OpReturn",
"class" : "Control-Flow",
- "opcode" : 253
+ "opcode" : 253,
+ "version" : "1.0"
},
{
"opname" : "OpReturnValue",
@@ -2647,12 +2879,14 @@
"opcode" : 254,
"operands" : [
{ "kind" : "IdRef", "name" : "'Value'" }
- ]
+ ],
+ "version": "1.0"
},
{
"opname" : "OpUnreachable",
"class" : "Control-Flow",
- "opcode" : 255
+ "opcode" : 255,
+ "version" : "1.0"
},
{
"opname" : "OpLifetimeStart",
@@ -2662,7 +2896,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "LiteralInteger", "name" : "'Size'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpLifetimeStop",
@@ -2672,7 +2907,8 @@
{ "kind" : "IdRef", "name" : "'Pointer'" },
{ "kind" : "LiteralInteger", "name" : "'Size'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupAsyncCopy",
@@ -2688,7 +2924,8 @@
{ "kind" : "IdRef", "name" : "'Stride'" },
{ "kind" : "IdRef", "name" : "'Event'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupWaitEvents",
@@ -2699,7 +2936,8 @@
{ "kind" : "IdRef", "name" : "'Num Events'" },
{ "kind" : "IdRef", "name" : "'Events List'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupAll",
@@ -2711,7 +2949,8 @@
{ "kind" : "IdScope", "name" : "'Execution'" },
{ "kind" : "IdRef", "name" : "'Predicate'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupAny",
@@ -2723,7 +2962,8 @@
{ "kind" : "IdScope", "name" : "'Execution'" },
{ "kind" : "IdRef", "name" : "'Predicate'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupBroadcast",
@@ -2736,7 +2976,8 @@
{ "kind" : "IdRef", "name" : "'Value'" },
{ "kind" : "IdRef", "name" : "'LocalId'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupIAdd",
@@ -2749,7 +2990,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupFAdd",
@@ -2762,7 +3004,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupFMin",
@@ -2775,7 +3018,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupUMin",
@@ -2788,7 +3032,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupSMin",
@@ -2801,7 +3046,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupFMax",
@@ -2814,7 +3060,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupUMax",
@@ -2827,7 +3074,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupSMax",
@@ -2840,7 +3088,8 @@
{ "kind" : "GroupOperation", "name" : "'Operation'" },
{ "kind" : "IdRef", "name" : "'X'" }
],
- "capabilities" : [ "Groups" ]
+ "capabilities" : [ "Groups" ],
+ "version": "1.0"
},
{
"opname" : "OpReadPipe",
@@ -2854,7 +3103,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpWritePipe",
@@ -2868,7 +3118,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpReservedReadPipe",
@@ -2884,7 +3135,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpReservedWritePipe",
@@ -2900,7 +3152,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpReserveReadPipePackets",
@@ -2914,7 +3167,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpReserveWritePipePackets",
@@ -2928,7 +3182,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpCommitReadPipe",
@@ -2940,7 +3195,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpCommitWritePipe",
@@ -2952,7 +3208,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpIsValidReserveId",
@@ -2963,7 +3220,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Reserve Id'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGetNumPipePackets",
@@ -2976,7 +3234,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGetMaxPipePackets",
@@ -2989,7 +3248,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupReserveReadPipePackets",
@@ -3004,7 +3264,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupReserveWritePipePackets",
@@ -3019,7 +3280,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupCommitReadPipe",
@@ -3032,7 +3294,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpGroupCommitWritePipe",
@@ -3045,7 +3308,8 @@
{ "kind" : "IdRef", "name" : "'Packet Size'" },
{ "kind" : "IdRef", "name" : "'Packet Alignment'" }
],
- "capabilities" : [ "Pipes" ]
+ "capabilities" : [ "Pipes" ],
+ "version": "1.0"
},
{
"opname" : "OpEnqueueMarker",
@@ -3059,7 +3323,8 @@
{ "kind" : "IdRef", "name" : "'Wait Events'" },
{ "kind" : "IdRef", "name" : "'Ret Event'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpEnqueueKernel",
@@ -3080,7 +3345,8 @@
{ "kind" : "IdRef", "name" : "'Param Align'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Local Size'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpGetKernelNDrangeSubGroupCount",
@@ -3095,7 +3361,8 @@
{ "kind" : "IdRef", "name" : "'Param Size'" },
{ "kind" : "IdRef", "name" : "'Param Align'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpGetKernelNDrangeMaxSubGroupSize",
@@ -3110,7 +3377,8 @@
{ "kind" : "IdRef", "name" : "'Param Size'" },
{ "kind" : "IdRef", "name" : "'Param Align'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpGetKernelWorkGroupSize",
@@ -3124,7 +3392,8 @@
{ "kind" : "IdRef", "name" : "'Param Size'" },
{ "kind" : "IdRef", "name" : "'Param Align'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpGetKernelPreferredWorkGroupSizeMultiple",
@@ -3138,7 +3407,8 @@
{ "kind" : "IdRef", "name" : "'Param Size'" },
{ "kind" : "IdRef", "name" : "'Param Align'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpRetainEvent",
@@ -3147,7 +3417,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Event'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpReleaseEvent",
@@ -3156,7 +3427,8 @@
"operands" : [
{ "kind" : "IdRef", "name" : "'Event'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpCreateUserEvent",
@@ -3166,7 +3438,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpIsValidEvent",
@@ -3177,7 +3450,8 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Event'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpSetUserEventStatus",
@@ -3187,7 +3461,8 @@
{ "kind" : "IdRef", "name" : "'Event'" },
{ "kind" : "IdRef", "name" : "'Status'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpCaptureEventProfilingInfo",
@@ -3198,7 +3473,8 @@
{ "kind" : "IdRef", "name" : "'Profiling Info'" },
{ "kind" : "IdRef", "name" : "'Value'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpGetDefaultQueue",
@@ -3208,7 +3484,8 @@
{ "kind" : "IdResultType" },
{ "kind" : "IdResult" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpBuildNDRange",
@@ -3221,7 +3498,8 @@
{ "kind" : "IdRef", "name" : "'LocalWorkSize'" },
{ "kind" : "IdRef", "name" : "'GlobalWorkOffset'" }
],
- "capabilities" : [ "DeviceEnqueue" ]
+ "capabilities" : [ "DeviceEnqueue" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseSampleImplicitLod",
@@ -3234,7 +3512,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseSampleExplicitLod",
@@ -3247,7 +3526,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseSampleDrefImplicitLod",
@@ -3261,7 +3541,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseSampleDrefExplicitLod",
@@ -3275,7 +3556,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseSampleProjImplicitLod",
@@ -3346,7 +3628,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseGather",
@@ -3360,7 +3643,8 @@
{ "kind" : "IdRef", "name" : "'Component'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseDrefGather",
@@ -3374,7 +3658,8 @@
{ "kind" : "IdRef", "name" : "'D~ref~'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseTexelsResident",
@@ -3385,12 +3670,14 @@
{ "kind" : "IdResult" },
{ "kind" : "IdRef", "name" : "'Resident Code'" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpNoLine",
"class" : "Debug",
- "opcode" : 317
+ "opcode" : 317,
+ "version" : "1.0"
},
{
"opname" : "OpAtomicFlagTestAndSet",
@@ -3403,7 +3690,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpAtomicFlagClear",
@@ -3414,7 +3702,8 @@
{ "kind" : "IdScope", "name" : "'Memory'" },
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" }
],
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"opname" : "OpImageSparseRead",
@@ -3427,7 +3716,8 @@
{ "kind" : "IdRef", "name" : "'Coordinate'" },
{ "kind" : "ImageOperands", "quantifier" : "?" }
],
- "capabilities" : [ "SparseResidency" ]
+ "capabilities" : [ "SparseResidency" ],
+ "version": "1.0"
},
{
"opname" : "OpSizeOf",
@@ -4494,8 +4784,79 @@
"version" : "1.6"
},
{
+ "opname" : "OpTypeCooperativeMatrixKHR",
+ "class" : "Type-Declaration",
+ "opcode" : 4456,
+ "operands" : [
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Component Type'" },
+ { "kind" : "IdScope", "name" : "'Scope'" },
+ { "kind" : "IdRef", "name" : "'Rows'" },
+ { "kind" : "IdRef", "name" : "'Columns'" },
+ { "kind" : "IdRef", "name" : "'Use'" }
+ ],
+ "capabilities" : [ "CooperativeMatrixKHR" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpCooperativeMatrixLoadKHR",
+ "class" : "Memory",
+ "opcode" : 4457,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Pointer'" },
+ { "kind" : "IdRef", "name" : "'MemoryLayout'" },
+ { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" },
+ { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" }
+ ],
+ "capabilities" : [ "CooperativeMatrixKHR" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpCooperativeMatrixStoreKHR",
+ "class" : "Memory",
+ "opcode" : 4458,
+ "operands" : [
+ { "kind" : "IdRef", "name" : "'Pointer'" },
+ { "kind" : "IdRef", "name" : "'Object'" },
+ { "kind" : "IdRef", "name" : "'MemoryLayout'" },
+ { "kind" : "IdRef", "name" : "'Stride'", "quantifier": "?" },
+ { "kind" : "MemoryAccess", "name" : "'Memory Operand'", "quantifier" : "?" }
+ ],
+ "capabilities" : [ "CooperativeMatrixKHR" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpCooperativeMatrixMulAddKHR",
+ "class" : "Arithmetic",
+ "opcode" : 4459,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'A'" },
+ { "kind" : "IdRef", "name" : "'B'" },
+ { "kind" : "IdRef", "name" : "'C'" },
+ { "kind" : "CooperativeMatrixOperands", "name" : "'Cooperative Matrix Operands'", "quantifier" : "?" }
+ ],
+ "capabilities" : [ "CooperativeMatrixKHR" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpCooperativeMatrixLengthKHR",
+ "class" : "Miscellaneous",
+ "opcode" : 4460,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Type'" }
+ ],
+ "capabilities" : [ "CooperativeMatrixKHR" ],
+ "version" : "None"
+ },
+ {
"opname" : "OpTypeRayQueryKHR",
- "class" : "Reserved",
+ "class" : "Type-Declaration",
"opcode" : 4472,
"operands" : [
{ "kind" : "IdResult" }
@@ -4690,6 +5051,70 @@
"version" : "None"
},
{
+ "opname" : "OpImageBlockMatchWindowSSDQCOM",
+ "class" : "Image",
+ "opcode" : 4500,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Target Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Target Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Reference Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Reference Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Block Size'" }
+ ],
+ "capabilities" : [ "TextureBlockMatch2QCOM" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpImageBlockMatchWindowSADQCOM",
+ "class" : "Image",
+ "opcode" : 4501,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Target Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Target Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Reference Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Reference Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Block Size'" }
+ ],
+ "capabilities" : [ "TextureBlockMatch2QCOM" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpImageBlockMatchGatherSSDQCOM",
+ "class" : "Image",
+ "opcode" : 4502,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Target Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Target Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Reference Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Reference Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Block Size'" }
+ ],
+ "capabilities" : [ "TextureBlockMatch2QCOM" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpImageBlockMatchGatherSADQCOM",
+ "class" : "Image",
+ "opcode" : 4503,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Target Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Target Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Reference Sampled Image'" },
+ { "kind" : "IdRef", "name" : "'Reference Coordinates'" },
+ { "kind" : "IdRef", "name" : "'Block Size'" }
+ ],
+ "capabilities" : [ "TextureBlockMatch2QCOM" ],
+ "version" : "None"
+ },
+ {
"opname" : "OpGroupIAddNonUniformAMD",
"class" : "Group",
"opcode" : 5000,
@@ -4851,6 +5276,65 @@
"version" : "None"
},
{
+ "opname" : "OpFinalizeNodePayloadsAMDX",
+ "class" : "Reserved",
+ "opcode" : 5075,
+ "operands" : [
+ { "kind" : "IdRef", "name": "'Payload Array'" }
+ ],
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpFinishWritingNodePayloadAMDX",
+ "class" : "Reserved",
+ "opcode" : 5078,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name": "'Payload'" }
+ ],
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpInitializeNodePayloadsAMDX",
+ "class" : "Reserved",
+ "opcode" : 5090,
+ "operands" : [
+ { "kind" : "IdRef", "name": "'Payload Array'" },
+ { "kind" : "IdScope", "name": "'Visibility'" },
+ { "kind" : "IdRef", "name": "'Payload Count'" },
+ { "kind" : "IdRef", "name": "'Node Index'" }
+ ],
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpGroupNonUniformQuadAllKHR",
+ "class" : "Non-Uniform",
+ "opcode" : 5110,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Predicate'" }
+ ],
+ "capabilities" : [ "QuadControlKHR" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpGroupNonUniformQuadAnyKHR",
+ "class" : "Non-Uniform",
+ "opcode" : 5111,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Predicate'" }
+ ],
+ "capabilities" : [ "QuadControlKHR" ],
+ "version" : "None"
+ },
+ {
"opname" : "OpHitObjectRecordHitMotionNV",
"class" : "Reserved",
"opcode" : 5249,
@@ -5297,7 +5781,7 @@
},
{
"opname" : "OpTypeHitObjectNV",
- "class" : "Reserved",
+ "class" : "Type-Declaration",
"opcode" : 5281,
"operands" : [
{ "kind" : "IdResult" }
@@ -5372,6 +5856,38 @@
"version" : "None"
},
{
+ "opname" : "OpFetchMicroTriangleVertexPositionNV",
+ "class" : "Reserved",
+ "opcode" : 5300,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Accel'" },
+ { "kind" : "IdRef", "name" : "'Instance Id'" },
+ { "kind" : "IdRef", "name" : "'Geometry Index'" },
+ { "kind" : "IdRef", "name" : "'Primitive Index'" },
+ { "kind" : "IdRef", "name" : "'Barycentric'" }
+ ],
+ "capabilities" : [ "DisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpFetchMicroTriangleVertexBarycentricNV",
+ "class" : "Reserved",
+ "opcode" : 5301,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Accel'" },
+ { "kind" : "IdRef", "name" : "'Instance Id'" },
+ { "kind" : "IdRef", "name" : "'Geometry Index'" },
+ { "kind" : "IdRef", "name" : "'Primitive Index'" },
+ { "kind" : "IdRef", "name" : "'Barycentric'" }
+ ],
+ "capabilities" : [ "DisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
"opname" : "OpReportIntersectionNV",
"class" : "Reserved",
"opcode" : 5334,
@@ -5504,7 +6020,7 @@
},
{
"opname" : "OpTypeAccelerationStructureNV",
- "class" : "Reserved",
+ "class" : "Type-Declaration",
"opcode" : 5341,
"operands" : [
{ "kind" : "IdResult" }
@@ -5515,7 +6031,7 @@
},
{
"opname" : "OpTypeAccelerationStructureKHR",
- "class" : "Reserved",
+ "class" : "Type-Declaration",
"opcode" : 5341,
"operands" : [
{ "kind" : "IdResult" }
@@ -5539,7 +6055,7 @@
},
{
"opname" : "OpTypeCooperativeMatrixNV",
- "class" : "Reserved",
+ "class" : "Type-Declaration",
"opcode" : 5358,
"operands" : [
{ "kind" : "IdResult" },
@@ -5736,6 +6252,24 @@
"version" : "None"
},
{
+ "opname" : "OpRawAccessChainNV",
+ "class" : "Memory",
+ "opcode" : 5398,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'Base'" },
+ { "kind" : "IdRef", "name" : "'Byte stride'" },
+ { "kind" : "IdRef", "name" : "'Element index'" },
+ { "kind" : "IdRef", "name" : "'Byte offset'" },
+ { "kind" : "RawAccessChainOperands", "quantifier" : "?" }
+ ],
+ "capabilities" : [
+ "RawAccessChainsNV"
+ ],
+ "version" : "None"
+ },
+ {
"opname" : "OpSubgroupShuffleINTEL",
"class" : "Group",
"opcode" : 5571,
@@ -6124,7 +6658,7 @@
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
],
- "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT" ],
+ "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ],
"version" : "None"
},
{
@@ -6139,7 +6673,7 @@
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
],
- "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT" ],
+ "capabilities" : [ "AtomicFloat16MinMaxEXT", "AtomicFloat32MinMaxEXT", "AtomicFloat64MinMaxEXT", "AtomicFloat16VectorNV" ],
"version" : "None"
},
{
@@ -9111,7 +9645,7 @@
{ "kind" : "IdMemorySemantics", "name" : "'Semantics'" },
{ "kind" : "IdRef", "name" : "'Value'" }
],
- "capabilities" : [ "AtomicFloat16AddEXT", "AtomicFloat32AddEXT", "AtomicFloat64AddEXT" ],
+ "capabilities" : [ "AtomicFloat16AddEXT", "AtomicFloat32AddEXT", "AtomicFloat64AddEXT", "AtomicFloat16VectorNV" ],
"extensions" : [ "SPV_EXT_shader_atomic_float_add" ],
"version" : "None"
},
@@ -9136,7 +9670,7 @@
"operands" : [
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Member 0 type', +\n'member 1 type', +\n..." }
],
- "capabilities" : [ "LongConstantCompositeINTEL" ],
+ "capabilities" : [ "LongCompositesINTEL" ],
"version" : "None"
},
{
@@ -9146,7 +9680,7 @@
"operands" : [
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
],
- "capabilities" : [ "LongConstantCompositeINTEL" ],
+ "capabilities" : [ "LongCompositesINTEL" ],
"version" : "None"
},
{
@@ -9156,10 +9690,22 @@
"operands" : [
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
],
- "capabilities" : [ "LongConstantCompositeINTEL" ],
+ "capabilities" : [ "LongCompositesINTEL" ],
"version" : "None"
},
{
+ "opname" : "OpCompositeConstructContinuedINTEL",
+ "class" : "Composite",
+ "opcode" : 6096,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "quantifier" : "*", "name" : "'Constituents'" }
+ ],
+ "capabilities" : [ "LongCompositesINTEL" ],
+ "version": "None"
+ },
+ {
"opname" : "OpConvertFToBF16INTEL",
"class" : "Conversion",
"opcode" : 6116,
@@ -9318,6 +9864,34 @@
],
"capabilities" : [ "GroupUniformArithmeticKHR" ],
"version" : "None"
+ },
+ {
+ "opname" : "OpMaskedGatherINTEL",
+ "class" : "Memory",
+ "opcode" : 6428,
+ "operands" : [
+ { "kind" : "IdResultType" },
+ { "kind" : "IdResult" },
+ { "kind" : "IdRef", "name" : "'PtrVector'" },
+ { "kind" : "LiteralInteger", "name" : "'Alignment'" },
+ { "kind" : "IdRef", "name" : "'Mask'" },
+ { "kind" : "IdRef", "name" : "'FillEmpty'" }
+ ],
+ "capabilities" : [ "MaskedGatherScatterINTEL" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpMaskedScatterINTEL",
+ "class" : "Memory",
+ "opcode" : 6429,
+ "operands" : [
+ { "kind" : "IdRef", "name" : "'InputVector'" },
+ { "kind" : "IdRef", "name" : "'PtrVector'" },
+ { "kind" : "LiteralInteger", "name" : "'Alignment'" },
+ { "kind" : "IdRef", "name" : "'Mask'" }
+ ],
+ "capabilities" : [ "MaskedGatherScatterINTEL" ],
+ "version" : "None"
}
],
"operand_kinds" : [
@@ -9335,14 +9909,16 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Lod",
"value" : "0x0002",
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Grad",
@@ -9350,14 +9926,16 @@
"parameters" : [
{ "kind" : "IdRef" },
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "ConstOffset",
"value" : "0x0008",
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Offset",
@@ -9365,7 +9943,8 @@
"capabilities" : [ "ImageGatherExtended" ],
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "ConstOffsets",
@@ -9373,14 +9952,16 @@
"capabilities" : [ "ImageGatherExtended" ],
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Sample",
"value" : "0x0040",
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "MinLod",
@@ -9388,7 +9969,8 @@
"capabilities" : [ "MinLod" ],
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "MakeTexelAvailable",
@@ -9474,7 +10056,8 @@
"value" : "0x10000",
"parameters" : [
{ "kind" : "IdRef" }
- ]
+ ],
+ "version": "1.0"
}
]
},
@@ -9484,38 +10067,62 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "NotNaN",
- "value" : "0x0001"
+ "value" : "0x0001",
+ "version" : "1.0"
},
{
"enumerant" : "NotInf",
- "value" : "0x0002"
+ "value" : "0x0002",
+ "version" : "1.0"
},
{
"enumerant" : "NSZ",
- "value" : "0x0004"
+ "value" : "0x0004",
+ "version" : "1.0"
},
{
"enumerant" : "AllowRecip",
- "value" : "0x0008"
+ "value" : "0x0008",
+ "version" : "1.0"
},
{
"enumerant" : "Fast",
- "value" : "0x0010"
+ "value" : "0x0010",
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "AllowContract",
+ "value" : "0x10000",
+ "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ],
+ "version" : "None"
},
{
"enumerant" : "AllowContractFastINTEL",
"value" : "0x10000",
- "capabilities" : [ "FPFastMathModeINTEL" ],
+ "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "AllowReassoc",
+ "value" : "0x20000",
+ "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ],
"version" : "None"
},
{
"enumerant" : "AllowReassocINTEL",
"value" : "0x20000",
- "capabilities" : [ "FPFastMathModeINTEL" ],
+ "capabilities" : [ "FloatControls2", "FPFastMathModeINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "AllowTransform",
+ "value" : "0x40000",
+ "capabilities" : [ "FloatControls2" ],
"version" : "None"
}
]
@@ -9526,15 +10133,18 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "Flatten",
- "value" : "0x0001"
+ "value" : "0x0001",
+ "version" : "1.0"
},
{
"enumerant" : "DontFlatten",
- "value" : "0x0002"
+ "value" : "0x0002",
+ "version" : "1.0"
}
]
},
@@ -9544,15 +10154,18 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "Unroll",
- "value" : "0x0001"
+ "value" : "0x0001",
+ "version" : "1.0"
},
{
"enumerant" : "DontUnroll",
- "value" : "0x0002"
+ "value" : "0x0002",
+ "version" : "1.0"
},
{
"enumerant" : "DependencyInfinite",
@@ -9702,23 +10315,28 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "Inline",
- "value" : "0x0001"
+ "value" : "0x0001",
+ "version" : "1.0"
},
{
"enumerant" : "DontInline",
- "value" : "0x0002"
+ "value" : "0x0002",
+ "version" : "1.0"
},
{
"enumerant" : "Pure",
- "value" : "0x0004"
+ "value" : "0x0004",
+ "version" : "1.0"
},
{
"enumerant" : "Const",
- "value" : "0x0008"
+ "value" : "0x0008",
+ "version" : "1.0"
},
{
"enumerant" : "OptNoneINTEL",
@@ -9734,53 +10352,65 @@
"enumerants" : [
{
"enumerant" : "Relaxed",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "Acquire",
- "value" : "0x0002"
+ "value" : "0x0002",
+ "version" : "1.0"
},
{
"enumerant" : "Release",
- "value" : "0x0004"
+ "value" : "0x0004",
+ "version" : "1.0"
},
{
"enumerant" : "AcquireRelease",
- "value" : "0x0008"
+ "value" : "0x0008",
+ "version" : "1.0"
},
{
"enumerant" : "SequentiallyConsistent",
- "value" : "0x0010"
+ "value" : "0x0010",
+ "version" : "1.0"
},
{
"enumerant" : "UniformMemory",
"value" : "0x0040",
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupMemory",
- "value" : "0x0080"
+ "value" : "0x0080",
+ "version" : "1.0"
},
{
"enumerant" : "WorkgroupMemory",
- "value" : "0x0100"
+ "value" : "0x0100",
+ "version" : "1.0"
},
{
"enumerant" : "CrossWorkgroupMemory",
- "value" : "0x0200"
+ "value" : "0x0200",
+ "version" : "1.0"
},
{
"enumerant" : "AtomicCounterMemory",
"value" : "0x0400",
- "capabilities" : [ "AtomicStorage" ]
+ "capabilities" : [ "AtomicStorage" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageMemory",
- "value" : "0x0800"
+ "value" : "0x0800",
+ "version" : "1.0"
},
{
"enumerant" : "OutputMemory",
@@ -9836,22 +10466,26 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "Volatile",
- "value" : "0x0001"
+ "value" : "0x0001",
+ "version" : "1.0"
},
{
"enumerant" : "Aligned",
"value" : "0x0002",
"parameters" : [
{ "kind" : "LiteralInteger" }
- ]
+ ],
+ "version" : "1.0"
},
{
"enumerant" : "Nontemporal",
- "value" : "0x0004"
+ "value" : "0x0004",
+ "version" : "1.0"
},
{
"enumerant" : "MakePointerAvailable",
@@ -9932,12 +10566,14 @@
"enumerants" : [
{
"enumerant" : "None",
- "value" : "0x0000"
+ "value" : "0x0000",
+ "version" : "1.0"
},
{
"enumerant" : "CmdExecTime",
"value" : "0x0001",
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
}
]
},
@@ -10050,40 +10686,95 @@
]
},
{
+ "category" : "BitEnum",
+ "kind" : "RawAccessChainOperands",
+ "enumerants" : [
+ {
+ "enumerant" : "None",
+ "value" : "0x0000"
+ },
+ {
+ "enumerant" : "RobustnessPerComponentNV",
+ "value" : "0x0001",
+ "capabilities" : [ "RawAccessChainsNV" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "RobustnessPerElementNV",
+ "value" : "0x0002",
+ "capabilities" : [ "RawAccessChainsNV" ],
+ "version" : "None"
+ }
+ ]
+ },
+ {
"category" : "ValueEnum",
"kind" : "SourceLanguage",
"enumerants" : [
{
"enumerant" : "Unknown",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "ESSL",
- "value" : 1
+ "value" : 1,
+ "version" : "1.0"
},
{
"enumerant" : "GLSL",
- "value" : 2
+ "value" : 2,
+ "version" : "1.0"
},
{
"enumerant" : "OpenCL_C",
- "value" : 3
+ "value" : 3,
+ "version" : "1.0"
},
{
"enumerant" : "OpenCL_CPP",
- "value" : 4
+ "value" : 4,
+ "version" : "1.0"
},
{
"enumerant" : "HLSL",
- "value" : 5
+ "value" : 5,
+ "version" : "1.0"
},
{
"enumerant" : "CPP_for_OpenCL",
- "value" : 6
+ "value" : 6,
+ "version" : "1.0"
},
{
"enumerant" : "SYCL",
- "value" : 7
+ "value" : 7,
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "HERO_C",
+ "value" : 8,
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "NZSL",
+ "value" : 9,
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "WGSL",
+ "value" : 10,
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "Slang",
+ "value" : 11,
+ "version" : "1.0"
+ },
+ {
+ "enumerant" : "Zig",
+ "value" : 12,
+ "version" : "1.0"
}
]
},
@@ -10094,37 +10785,44 @@
{
"enumerant" : "Vertex",
"value" : 0,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "TessellationControl",
"value" : 1,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "TessellationEvaluation",
"value" : 2,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "Geometry",
"value" : 3,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "Fragment",
"value" : 4,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "GLCompute",
"value" : 5,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Kernel",
"value" : 6,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "TaskNV",
@@ -10230,17 +10928,20 @@
"enumerants" : [
{
"enumerant" : "Logical",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "Physical32",
"value" : 1,
- "capabilities" : [ "Addresses" ]
+ "capabilities" : [ "Addresses" ],
+ "version": "1.0"
},
{
"enumerant" : "Physical64",
"value" : 2,
- "capabilities" : [ "Addresses" ]
+ "capabilities" : [ "Addresses" ],
+ "version": "1.0"
},
{
"enumerant" : "PhysicalStorageBuffer64",
@@ -10265,17 +10966,20 @@
{
"enumerant" : "Simple",
"value" : 0,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "GLSL450",
"value" : 1,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "OpenCL",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Vulkan",
@@ -10302,82 +11006,98 @@
"capabilities" : [ "Geometry" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Number of <<Invocation,invocations>>'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "SpacingEqual",
"value" : 1,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "SpacingFractionalEven",
"value" : 2,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "SpacingFractionalOdd",
"value" : 3,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "VertexOrderCw",
"value" : 4,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "VertexOrderCcw",
"value" : 5,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "PixelCenterInteger",
"value" : 6,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "OriginUpperLeft",
"value" : 7,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "OriginLowerLeft",
"value" : 8,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "EarlyFragmentTests",
"value" : 9,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "PointMode",
"value" : 10,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "Xfb",
"value" : 11,
- "capabilities" : [ "TransformFeedback" ]
+ "capabilities" : [ "TransformFeedback" ],
+ "version": "1.0"
},
{
"enumerant" : "DepthReplacing",
"value" : 12,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "DepthGreater",
"value" : 14,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "DepthLess",
"value" : 15,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "DepthUnchanged",
"value" : 16,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "LocalSize",
@@ -10386,7 +11106,8 @@
{ "kind" : "LiteralInteger", "name" : "'x size'" },
{ "kind" : "LiteralInteger", "name" : "'y size'" },
{ "kind" : "LiteralInteger", "name" : "'z size'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "LocalSizeHint",
@@ -10396,42 +11117,50 @@
{ "kind" : "LiteralInteger", "name" : "'x size'" },
{ "kind" : "LiteralInteger", "name" : "'y size'" },
{ "kind" : "LiteralInteger", "name" : "'z size'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "InputPoints",
"value" : 19,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "InputLines",
"value" : 20,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "InputLinesAdjacency",
"value" : 21,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "Triangles",
"value" : 22,
- "capabilities" : [ "Geometry", "Tessellation" ]
+ "capabilities" : [ "Geometry", "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "InputTrianglesAdjacency",
"value" : 23,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "Quads",
"value" : 24,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "Isolines",
"value" : 25,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "OutputVertices",
@@ -10439,22 +11168,26 @@
"capabilities" : [ "Geometry", "Tessellation", "MeshShadingNV", "MeshShadingEXT" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Vertex count'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "OutputPoints",
"value" : 27,
- "capabilities" : [ "Geometry", "MeshShadingNV", "MeshShadingEXT" ]
+ "capabilities" : [ "Geometry", "MeshShadingNV", "MeshShadingEXT" ],
+ "version": "1.0"
},
{
"enumerant" : "OutputLineStrip",
"value" : 28,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "OutputTriangleStrip",
"value" : 29,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "VecTypeHint",
@@ -10462,12 +11195,14 @@
"capabilities" : [ "Kernel" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Vector type'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "ContractionOff",
"value" : 31,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Initializer",
@@ -10626,6 +11361,52 @@
"version" : "None"
},
{
+ "enumerant" : "CoalescingAMDX",
+ "value" : 5069,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MaxNodeRecursionAMDX",
+ "value" : 5071,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Number of recursions'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "StaticNumWorkgroupsAMDX",
+ "value" : 5072,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'x size'" },
+ { "kind" : "IdRef", "name" : "'y size'" },
+ { "kind" : "IdRef", "name" : "'z size'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ShaderIndexAMDX",
+ "value" : 5073,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Shader Index'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MaxNumWorkgroupsAMDX",
+ "value" : 5077,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'x size'" },
+ { "kind" : "IdRef", "name" : "'y size'" },
+ { "kind" : "IdRef", "name" : "'z size'" }
+ ],
+ "version" : "None"
+ },
+ {
"enumerant": "StencilRefUnchangedFrontAMD",
"value": 5079,
"capabilities": [ "StencilExportEXT" ],
@@ -10668,6 +11449,18 @@
"version": "None"
},
{
+ "enumerant": "QuadDerivativesKHR",
+ "value": 5088,
+ "capabilities": [ "QuadControlKHR" ],
+ "version": "None"
+ },
+ {
+ "enumerant" : "RequireFullQuadsKHR",
+ "value" : 5089,
+ "capabilities" : [ "QuadControlKHR" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "OutputLinesNV",
"value" : 5269,
"capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ],
@@ -10865,6 +11658,23 @@
"version" : "None"
},
{
+ "enumerant" : "MaximallyReconvergesKHR",
+ "value" : 6023,
+ "capabilities" : [ "Shader" ],
+ "extensions" : [ "SPV_KHR_maximal_reconvergence" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "FPFastMathDefault",
+ "value" : 6028,
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Target Type'" },
+ { "kind" : "IdRef", "name" : "'Fast-Math Mode'" }
+ ],
+ "capabilities" : [ "FloatControls2" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "StreamingInterfaceINTEL",
"value" : 6154,
"parameters" : [
@@ -10890,6 +11700,33 @@
],
"capabilities" : [ "VectorComputeINTEL" ],
"version" : "None"
+ },
+ {
+ "enumerant" : "MaximumRegistersINTEL",
+ "value" : 6461,
+ "parameters" : [
+ { "kind" : "LiteralInteger", "name" : "'Number of Registers'" }
+ ],
+ "capabilities" : [ "RegisterLimitsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MaximumRegistersIdINTEL",
+ "value" : 6462,
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Number of Registers'" }
+ ],
+ "capabilities" : [ "RegisterLimitsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "NamedMaximumRegistersINTEL",
+ "value" : 6463,
+ "parameters" : [
+ { "kind" : "NamedMaximumNumberOfRegisters", "name" : "'Named Maximum Number of Registers'" }
+ ],
+ "capabilities" : [ "RegisterLimitsINTEL" ],
+ "version" : "None"
}
]
},
@@ -10899,57 +11736,69 @@
"enumerants" : [
{
"enumerant" : "UniformConstant",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "Input",
- "value" : 1
+ "value" : 1,
+ "version" : "1.0"
},
{
"enumerant" : "Uniform",
"value" : 2,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Output",
"value" : 3,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Workgroup",
- "value" : 4
+ "value" : 4,
+ "version" : "1.0"
},
{
"enumerant" : "CrossWorkgroup",
- "value" : 5
+ "value" : 5,
+ "version" : "1.0"
},
{
"enumerant" : "Private",
"value" : 6,
- "capabilities" : [ "Shader", "VectorComputeINTEL" ]
+ "capabilities" : [ "Shader", "VectorComputeINTEL" ],
+ "version": "1.0"
},
{
"enumerant" : "Function",
- "value" : 7
+ "value" : 7,
+ "version" : "1.0"
},
{
"enumerant" : "Generic",
"value" : 8,
- "capabilities" : [ "GenericPointer" ]
+ "capabilities" : [ "GenericPointer" ],
+ "version": "1.0"
},
{
"enumerant" : "PushConstant",
"value" : 9,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "AtomicCounter",
"value" : 10,
- "capabilities" : [ "AtomicStorage" ]
+ "capabilities" : [ "AtomicStorage" ],
+ "version": "1.0"
},
{
"enumerant" : "Image",
- "value" : 11
+ "value" : 11,
+ "version" : "1.0"
},
{
"enumerant" : "StorageBuffer",
@@ -10968,6 +11817,18 @@
"version" : "None"
},
{
+ "enumerant" : "NodePayloadAMDX",
+ "value" : 5068,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "NodeOutputPayloadAMDX",
+ "value" : 5076,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "CallableDataNV",
"value" : 5328,
"extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ],
@@ -11112,35 +11973,42 @@
{
"enumerant" : "1D",
"value" : 0,
- "capabilities" : [ "Sampled1D" ]
+ "capabilities" : [ "Sampled1D" ],
+ "version": "1.0"
},
{
"enumerant" : "2D",
- "value" : 1
+ "value" : 1,
+ "version" : "1.0"
},
{
"enumerant" : "3D",
- "value" : 2
+ "value" : 2,
+ "version" : "1.0"
},
{
"enumerant" : "Cube",
"value" : 3,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rect",
"value" : 4,
- "capabilities" : [ "SampledRect" ]
+ "capabilities" : [ "SampledRect" ],
+ "version": "1.0"
},
{
"enumerant" : "Buffer",
"value" : 5,
- "capabilities" : [ "SampledBuffer" ]
+ "capabilities" : [ "SampledBuffer" ],
+ "version": "1.0"
},
{
"enumerant" : "SubpassData",
"value" : 6,
- "capabilities" : [ "InputAttachment" ]
+ "capabilities" : [ "InputAttachment" ],
+ "version": "1.0"
},
{
"enumerant" : "TileImageDataEXT",
@@ -11157,27 +12025,27 @@
{
"enumerant" : "None",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "ClampToEdge",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Clamp",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Repeat",
"value" : 3,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RepeatMirrored",
"value" : 4,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
}
]
},
@@ -11188,12 +12056,12 @@
{
"enumerant" : "Nearest",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Linear",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
}
]
},
@@ -11203,212 +12071,254 @@
"enumerants" : [
{
"enumerant" : "Unknown",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "Rgba32f",
"value" : 1,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba16f",
"value" : 2,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "R32f",
"value" : 3,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba8",
"value" : 4,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba8Snorm",
"value" : 5,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg32f",
"value" : 6,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg16f",
"value" : 7,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R11fG11fB10f",
"value" : 8,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R16f",
"value" : 9,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba16",
"value" : 10,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgb10A2",
"value" : 11,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg16",
"value" : 12,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg8",
"value" : 13,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R16",
"value" : 14,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R8",
"value" : 15,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba16Snorm",
"value" : 16,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg16Snorm",
"value" : 17,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg8Snorm",
"value" : 18,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R16Snorm",
"value" : 19,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R8Snorm",
"value" : 20,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba32i",
"value" : 21,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba16i",
"value" : 22,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba8i",
"value" : 23,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "R32i",
"value" : 24,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg32i",
"value" : 25,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg16i",
"value" : 26,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg8i",
"value" : 27,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R16i",
"value" : 28,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R8i",
"value" : 29,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba32ui",
"value" : 30,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba16ui",
"value" : 31,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgba8ui",
"value" : 32,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "R32ui",
"value" : 33,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Rgb10a2ui",
"value" : 34,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg32ui",
"value" : 35,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg16ui",
"value" : 36,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "Rg8ui",
"value" : 37,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R16ui",
"value" : 38,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
{
"enumerant" : "R8ui",
"value" : 39,
- "capabilities" : [ "StorageImageExtendedFormats" ]
+ "capabilities" : [ "StorageImageExtendedFormats" ],
+ "version": "1.0"
},
- {
+ {
"enumerant" : "R64ui",
"value" : 40,
- "capabilities" : [ "Int64ImageEXT" ]
+ "capabilities" : [ "Int64ImageEXT" ],
+ "version": "1.0"
},
{
"enumerant" : "R64i",
"value" : 41,
- "capabilities" : [ "Int64ImageEXT" ]
+ "capabilities" : [ "Int64ImageEXT" ],
+ "version": "1.0"
}
]
},
@@ -11419,102 +12329,102 @@
{
"enumerant" : "R",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "A",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RG",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RA",
"value" : 3,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RGB",
"value" : 4,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RGBA",
"value" : 5,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "BGRA",
"value" : 6,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "ARGB",
"value" : 7,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Intensity",
"value" : 8,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Luminance",
"value" : 9,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Rx",
"value" : 10,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RGx",
"value" : 11,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "RGBx",
"value" : 12,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Depth",
"value" : 13,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "DepthStencil",
"value" : 14,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "sRGB",
"value" : 15,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "sRGBx",
"value" : 16,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "sRGBA",
"value" : 17,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "sBGRA",
"value" : 18,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "ABGR",
"value" : 19,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
}
]
},
@@ -11525,87 +12435,97 @@
{
"enumerant" : "SnormInt8",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "SnormInt16",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormInt8",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormInt16",
"value" : 3,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormShort565",
"value" : 4,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormShort555",
"value" : 5,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormInt101010",
"value" : 6,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "SignedInt8",
"value" : 7,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "SignedInt16",
"value" : 8,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "SignedInt32",
"value" : 9,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnsignedInt8",
"value" : 10,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnsignedInt16",
"value" : 11,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnsignedInt32",
"value" : 12,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "HalfFloat",
"value" : 13,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "Float",
"value" : 14,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormInt24",
"value" : 15,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
},
{
"enumerant" : "UnormInt101010_2",
"value" : 16,
- "capabilities" : [ "Kernel" ]
+ "version": "1.0"
+ },
+ {
+ "enumerant" : "UnsignedIntRaw10EXT",
+ "value" : 19,
+ "version": "1.0"
+ },
+ {
+ "enumerant" : "UnsignedIntRaw12EXT",
+ "value" : 20,
+ "version": "1.0"
}
]
},
@@ -11615,19 +12535,23 @@
"enumerants" : [
{
"enumerant" : "RTE",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "RTZ",
- "value" : 1
+ "value" : 1,
+ "version" : "1.0"
},
{
"enumerant" : "RTP",
- "value" : 2
+ "value" : 2,
+ "version" : "1.0"
},
{
"enumerant" : "RTN",
- "value" : 3
+ "value" : 3,
+ "version" : "1.0"
}
]
},
@@ -11646,7 +12570,7 @@
"value" : 1,
"capabilities" : [ "FunctionFloatControlINTEL" ],
"version" : "None"
- }
+ }
]
},
{
@@ -11758,12 +12682,14 @@
{
"enumerant" : "Export",
"value" : 0,
- "capabilities" : [ "Linkage" ]
+ "capabilities" : [ "Linkage" ],
+ "version": "1.0"
},
{
"enumerant" : "Import",
"value" : 1,
- "capabilities" : [ "Linkage" ]
+ "capabilities" : [ "Linkage" ],
+ "version": "1.0"
},
{
"enumerant" : "LinkOnceODR",
@@ -11781,17 +12707,50 @@
{
"enumerant" : "ReadOnly",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "WriteOnly",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "ReadWrite",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "HostAccessQualifier",
+ "enumerants" : [
+ {
+ "enumerant" : "NoneINTEL",
+ "value" : 0,
+ "capabilities" : [ "GlobalVariableHostAccessINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ReadINTEL",
+ "value" : 1,
+ "capabilities" : [ "GlobalVariableHostAccessINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "WriteINTEL",
+ "value" : 2,
+ "capabilities" : [ "GlobalVariableHostAccessINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ReadWriteINTEL",
+ "value" : 3,
+ "capabilities" : [ "GlobalVariableHostAccessINTEL" ],
+ "version" : "None"
}
]
},
@@ -11802,47 +12761,56 @@
{
"enumerant" : "Zext",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Sext",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "ByVal",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Sret",
"value" : 3,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "NoAlias",
"value" : 4,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "NoCapture",
"value" : 5,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "NoWrite",
"value" : 6,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "NoReadWrite",
"value" : 7,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "RuntimeAlignedINTEL",
"value" : 5940,
- "capabilities" : [ "RuntimeAlignedAttributeINTEL" ]
+ "capabilities" : [ "RuntimeAlignedAttributeINTEL" ],
+ "version": "1.0"
}
]
},
@@ -11853,7 +12821,8 @@
{
"enumerant" : "RelaxedPrecision",
"value" : 0,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SpecId",
@@ -11861,28 +12830,33 @@
"capabilities" : [ "Shader", "Kernel" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Specialization Constant ID'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Block",
"value" : 2,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "BufferBlock",
"value" : 3,
"capabilities" : [ "Shader" ],
+ "version": "1.0",
"lastVersion" : "1.3"
},
{
"enumerant" : "RowMajor",
"value" : 4,
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"enumerant" : "ColMajor",
"value" : 5,
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"enumerant" : "ArrayStride",
@@ -11890,7 +12864,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Array Stride'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "MatrixStride",
@@ -11898,93 +12873,112 @@
"capabilities" : [ "Matrix" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Matrix Stride'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "GLSLShared",
"value" : 8,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "GLSLPacked",
"value" : 9,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "CPacked",
"value" : 10,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "BuiltIn",
"value" : 11,
"parameters" : [
{ "kind" : "BuiltIn" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "NoPerspective",
"value" : 13,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Flat",
"value" : 14,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Patch",
"value" : 15,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "Centroid",
"value" : 16,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Sample",
"value" : 17,
- "capabilities" : [ "SampleRateShading" ]
+ "capabilities" : [ "SampleRateShading" ],
+ "version": "1.0"
},
{
"enumerant" : "Invariant",
"value" : 18,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Restrict",
- "value" : 19
+ "value" : 19,
+ "version" : "1.0"
},
{
"enumerant" : "Aliased",
- "value" : 20
+ "value" : 20,
+ "version" : "1.0"
},
{
"enumerant" : "Volatile",
- "value" : 21
+ "value" : 21,
+ "version" : "1.0"
},
{
"enumerant" : "Constant",
"value" : 22,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Coherent",
- "value" : 23
+ "value" : 23,
+ "version": "1.0"
},
{
"enumerant" : "NonWritable",
- "value" : 24
+ "value" : 24,
+ "version": "1.0"
},
{
"enumerant" : "NonReadable",
- "value" : 25
+ "value" : 25,
+ "version": "1.0"
},
{
"enumerant" : "Uniform",
"value" : 26,
- "capabilities" : [ "Shader", "UniformDecoration" ]
+ "capabilities" : [ "Shader", "UniformDecoration" ],
+ "version": "1.0"
},
{
"enumerant" : "UniformId",
@@ -11998,7 +12992,8 @@
{
"enumerant" : "SaturatedConversion",
"value" : 28,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Stream",
@@ -12006,7 +13001,8 @@
"capabilities" : [ "GeometryStreams" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Stream Number'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Location",
@@ -12014,7 +13010,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Location'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Component",
@@ -12022,7 +13019,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Component'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Index",
@@ -12030,7 +13028,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Index'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Binding",
@@ -12038,7 +13037,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Binding Point'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "DescriptorSet",
@@ -12046,7 +13046,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Descriptor Set'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Offset",
@@ -12054,7 +13055,8 @@
"capabilities" : [ "Shader" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Byte Offset'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "XfbBuffer",
@@ -12062,7 +13064,8 @@
"capabilities" : [ "TransformFeedback" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'XFB Buffer Number'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "XfbStride",
@@ -12070,7 +13073,8 @@
"capabilities" : [ "TransformFeedback" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'XFB Stride'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "FuncParamAttr",
@@ -12078,22 +13082,25 @@
"capabilities" : [ "Kernel" ],
"parameters" : [
{ "kind" : "FunctionParameterAttribute", "name" : "'Function Parameter Attribute'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "FPRoundingMode",
"value" : 39,
"parameters" : [
{ "kind" : "FPRoundingMode", "name" : "'Floating-Point Rounding Mode'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "FPFastMathMode",
"value" : 40,
- "capabilities" : [ "Kernel" ],
+ "capabilities" : [ "Kernel", "FloatControls2" ],
"parameters" : [
{ "kind" : "FPFastMathMode", "name" : "'Fast-Math Mode'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "LinkageAttributes",
@@ -12102,12 +13109,14 @@
"parameters" : [
{ "kind" : "LiteralString", "name" : "'Name'" },
{ "kind" : "LinkageType", "name" : "'Linkage Type'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "NoContraction",
"value" : 42,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "InputAttachmentIndex",
@@ -12115,7 +13124,8 @@
"capabilities" : [ "InputAttachment" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Attachment Index'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "Alignment",
@@ -12123,7 +13133,8 @@
"capabilities" : [ "Kernel" ],
"parameters" : [
{ "kind" : "LiteralInteger", "name" : "'Alignment'" }
- ]
+ ],
+ "version": "1.0"
},
{
"enumerant" : "MaxByteOffset",
@@ -12177,12 +13188,51 @@
"version" : "None"
},
{
+ "enumerant" : "BlockMatchSamplerQCOM",
+ "value" : 4499,
+ "extensions" : [ "SPV_QCOM_image_processing2" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "ExplicitInterpAMD",
"value" : 4999,
"extensions" : [ "SPV_AMD_shader_explicit_vertex_parameter" ],
"version" : "None"
},
{
+ "enumerant" : "NodeSharesPayloadLimitsWithAMDX",
+ "value" : 5019,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Payload Array'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "NodeMaxPayloadsAMDX",
+ "value" : 5020,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "IdRef", "name" : "'Max number of payloads'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "TrackFinishWritingAMDX",
+ "value" : 5078,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "PayloadNodeNameAMDX",
+ "value" : 5091,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "parameters" : [
+ { "kind" : "LiteralString", "name" : "'Node Name'" }
+ ],
+ "version" : "None"
+ },
+ {
"enumerant" : "OverrideCoverageNV",
"value" : 5248,
"capabilities" : [ "SampleMaskOverrideCoverageNV" ],
@@ -12565,6 +13615,30 @@
"version" : "None"
},
{
+ "enumerant" : "StridesizeINTEL",
+ "value" : 5883,
+ "parameters" : [
+ { "kind" : "LiteralInteger", "name" : "'Stride Size'" }
+ ],
+ "capabilities" : [ "FPGAMemoryAttributesINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "WordsizeINTEL",
+ "value" : 5884,
+ "parameters" : [
+ { "kind" : "LiteralInteger", "name" : "'Word Size'" }
+ ],
+ "capabilities" : [ "FPGAMemoryAttributesINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "TrueDualPortINTEL",
+ "value" : 5885,
+ "capabilities" : [ "FPGAMemoryAttributesINTEL" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "BurstCoalesceINTEL",
"value" : 5899,
"capabilities" : [ "FPGAMemoryAccessesINTEL" ],
@@ -12708,6 +13782,21 @@
"version" : "None"
},
{
+ "enumerant" : "StallFreeINTEL",
+ "value" : 6151,
+ "capabilities" : [ "FPGAClusterAttributesV2INTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "FPMaxErrorDecorationINTEL",
+ "value" : 6170,
+ "parameters" : [
+ { "kind" : "LiteralFloat", "name" : "'Max Error'" }
+ ],
+ "capabilities" : [ "FPMaxErrorINTEL" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "LatencyControlLabelINTEL",
"value" : 6172,
"parameters" : [
@@ -12798,6 +13887,54 @@
"value" : 6183,
"capabilities" : [ "FPGAArgumentInterfacesINTEL" ],
"version" : "None"
+ },
+ {
+ "enumerant" : "HostAccessINTEL",
+ "value" : 6188,
+ "parameters": [
+ { "kind" : "HostAccessQualifier", "name" : "'Access'" },
+ { "kind" : "LiteralString", "name" : "'Name'" }
+ ],
+ "capabilities" : [ "GlobalVariableHostAccessINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "InitModeINTEL",
+ "value" : 6190,
+ "parameters": [
+ { "kind" : "InitializationModeQualifier", "name" : "'Trigger'" }
+ ],
+ "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ImplementInRegisterMapINTEL",
+ "value" : 6191,
+ "parameters": [
+ { "kind" : "LiteralInteger", "name" : "Value" }
+ ],
+ "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "CacheControlLoadINTEL",
+ "value" : 6442,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "parameters" : [
+ { "kind" : "LiteralInteger", "name" : "'Cache Level'" },
+ { "kind" : "LoadCacheControl", "name" : "'Cache Control'" }
+ ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "CacheControlStoreINTEL",
+ "value" : 6443,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "parameters" : [
+ { "kind" : "LiteralInteger", "name" : "'Cache Level'" },
+ { "kind" : "StoreCacheControl", "name" : "'Cache Control'" }
+ ],
+ "version" : "None"
}
]
},
@@ -12808,226 +13945,272 @@
{
"enumerant" : "Position",
"value" : 0,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "PointSize",
"value" : 1,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "ClipDistance",
"value" : 3,
- "capabilities" : [ "ClipDistance" ]
+ "capabilities" : [ "ClipDistance" ],
+ "version": "1.0"
},
{
"enumerant" : "CullDistance",
"value" : 4,
- "capabilities" : [ "CullDistance" ]
+ "capabilities" : [ "CullDistance" ],
+ "version": "1.0"
},
{
"enumerant" : "VertexId",
"value" : 5,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "InstanceId",
"value" : 6,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "PrimitiveId",
"value" : 7,
- "capabilities" : [ "Geometry", "Tessellation", "RayTracingNV", "RayTracingKHR", "MeshShadingNV", "MeshShadingEXT" ]
+ "capabilities" : [ "Geometry", "Tessellation", "RayTracingNV", "RayTracingKHR", "MeshShadingNV", "MeshShadingEXT" ],
+ "version": "1.0"
},
{
"enumerant" : "InvocationId",
"value" : 8,
- "capabilities" : [ "Geometry", "Tessellation" ]
+ "capabilities" : [ "Geometry", "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "Layer",
"value" : 9,
- "capabilities" : [ "Geometry", "ShaderLayer", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ]
+ "capabilities" : [ "Geometry", "ShaderLayer", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ],
+ "version": "1.0"
},
{
"enumerant" : "ViewportIndex",
"value" : 10,
- "capabilities" : [ "MultiViewport", "ShaderViewportIndex", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ]
+ "capabilities" : [ "MultiViewport", "ShaderViewportIndex", "ShaderViewportIndexLayerEXT", "MeshShadingNV", "MeshShadingEXT" ],
+ "version": "1.0"
},
{
"enumerant" : "TessLevelOuter",
"value" : 11,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "TessLevelInner",
"value" : 12,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "TessCoord",
"value" : 13,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "PatchVertices",
"value" : 14,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "FragCoord",
"value" : 15,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "PointCoord",
"value" : 16,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "FrontFacing",
"value" : 17,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SampleId",
"value" : 18,
- "capabilities" : [ "SampleRateShading" ]
+ "capabilities" : [ "SampleRateShading" ],
+ "version": "1.0"
},
{
"enumerant" : "SamplePosition",
"value" : 19,
- "capabilities" : [ "SampleRateShading" ]
+ "capabilities" : [ "SampleRateShading" ],
+ "version": "1.0"
},
{
"enumerant" : "SampleMask",
"value" : 20,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "FragDepth",
"value" : 22,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "HelperInvocation",
"value" : 23,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "NumWorkgroups",
- "value" : 24
+ "value" : 24,
+ "version" : "1.0"
},
{
"enumerant" : "WorkgroupSize",
- "value" : 25
+ "value" : 25,
+ "version" : "1.0"
},
{
"enumerant" : "WorkgroupId",
- "value" : 26
+ "value" : 26,
+ "version" : "1.0"
},
{
"enumerant" : "LocalInvocationId",
- "value" : 27
+ "value" : 27,
+ "version" : "1.0"
},
{
"enumerant" : "GlobalInvocationId",
- "value" : 28
+ "value" : 28,
+ "version" : "1.0"
},
{
"enumerant" : "LocalInvocationIndex",
- "value" : 29
+ "value" : 29,
+ "version" : "1.0"
},
{
"enumerant" : "WorkDim",
"value" : 30,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "GlobalSize",
"value" : 31,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "EnqueuedWorkgroupSize",
"value" : 32,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "GlobalOffset",
"value" : 33,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "GlobalLinearId",
"value" : 34,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupSize",
"value" : 36,
- "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ]
+ "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupMaxSize",
"value" : 37,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "NumSubgroups",
"value" : 38,
- "capabilities" : [ "Kernel", "GroupNonUniform" ]
+ "capabilities" : [ "Kernel", "GroupNonUniform" ],
+ "version": "1.0"
},
{
"enumerant" : "NumEnqueuedSubgroups",
"value" : 39,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupId",
"value" : 40,
- "capabilities" : [ "Kernel", "GroupNonUniform" ]
+ "capabilities" : [ "Kernel", "GroupNonUniform" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupLocalInvocationId",
"value" : 41,
- "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ]
+ "capabilities" : [ "Kernel", "GroupNonUniform", "SubgroupBallotKHR" ],
+ "version": "1.0"
},
{
"enumerant" : "VertexIndex",
"value" : 42,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "InstanceIndex",
"value" : 43,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "CoreIDARM",
"value" : 4160,
- "capabilities" : [ "CoreBuiltinsARM" ]
+ "capabilities" : [ "CoreBuiltinsARM" ],
+ "version": "1.0"
},
{
"enumerant" : "CoreCountARM",
"value" : 4161,
- "capabilities" : [ "CoreBuiltinsARM" ]
+ "capabilities" : [ "CoreBuiltinsARM" ],
+ "version": "1.0"
},
{
"enumerant" : "CoreMaxIDARM",
"value" : 4162,
- "capabilities" : [ "CoreBuiltinsARM" ]
+ "capabilities" : [ "CoreBuiltinsARM" ],
+ "version": "1.0"
},
{
"enumerant" : "WarpIDARM",
"value" : 4163,
- "capabilities" : [ "CoreBuiltinsARM" ]
+ "capabilities" : [ "CoreBuiltinsARM" ],
+ "version": "1.0"
},
{
"enumerant" : "WarpMaxIDARM",
"value" : 4164,
- "capabilities" : [ "CoreBuiltinsARM" ]
+ "capabilities" : [ "CoreBuiltinsARM" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupEqMask",
@@ -13193,6 +14376,18 @@
"version" : "None"
},
{
+ "enumerant" : "CoalescedInputCountAMDX",
+ "value" : 5021,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ShaderIndexAMDX",
+ "value" : 5073,
+ "capabilities" : [ "ShaderEnqueueAMDX" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "ViewportMaskNV",
"value" : 5253,
"capabilities" : [ "ShaderViewportMaskNV", "MeshShadingNV" ],
@@ -13563,6 +14758,18 @@
"version" : "None"
},
{
+ "enumerant" : "HitMicroTriangleVertexPositionsNV",
+ "value" : 5337,
+ "capabilities" : [ "RayTracingDisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "HitMicroTriangleVertexBarycentricsNV",
+ "value" : 5344,
+ "capabilities" : [ "RayTracingDisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "IncomingRayFlagsNV",
"value" : 5351,
"capabilities" : [ "RayTracingNV" , "RayTracingKHR" ],
@@ -13612,6 +14819,18 @@
"version" : "None"
},
{
+ "enumerant" : "HitKindFrontFacingMicroTriangleNV",
+ "value" : 5405,
+ "capabilities" : [ "RayTracingDisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "HitKindBackFacingMicroTriangleNV",
+ "value" : 5406,
+ "capabilities" : [ "RayTracingDisplacementMicromapNV" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "CullMaskKHR",
"value" : 6021,
"capabilities" : [ "RayCullMaskKHR" ],
@@ -13626,23 +14845,28 @@
"enumerants" : [
{
"enumerant" : "CrossDevice",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "Device",
- "value" : 1
+ "value" : 1,
+ "version" : "1.0"
},
{
"enumerant" : "Workgroup",
- "value" : 2
+ "value" : 2,
+ "version" : "1.0"
},
{
"enumerant" : "Subgroup",
- "value" : 3
+ "value" : 3,
+ "version" : "1.0"
},
{
"enumerant" : "Invocation",
- "value" : 4
+ "value" : 4,
+ "version" : "1.0"
},
{
"enumerant" : "QueueFamily",
@@ -13671,17 +14895,20 @@
{
"enumerant" : "Reduce",
"value" : 0,
- "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ]
+ "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ],
+ "version": "1.0"
},
{
"enumerant" : "InclusiveScan",
"value" : 1,
- "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ]
+ "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ],
+ "version": "1.0"
},
{
"enumerant" : "ExclusiveScan",
"value" : 2,
- "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ]
+ "capabilities" : [ "Kernel", "GroupNonUniformArithmetic", "GroupNonUniformBallot" ],
+ "version": "1.0"
},
{
"enumerant" : "ClusteredReduce",
@@ -13719,17 +14946,20 @@
{
"enumerant" : "NoWait",
"value" : 0,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "WaitKernel",
"value" : 1,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "WaitWorkGroup",
"value" : 2,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
}
]
},
@@ -13739,272 +14969,328 @@
"enumerants" : [
{
"enumerant" : "Matrix",
- "value" : 0
+ "value" : 0,
+ "version" : "1.0"
},
{
"enumerant" : "Shader",
"value" : 1,
- "capabilities" : [ "Matrix" ]
+ "capabilities" : [ "Matrix" ],
+ "version": "1.0"
},
{
"enumerant" : "Geometry",
"value" : 2,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Tessellation",
"value" : 3,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Addresses",
- "value" : 4
+ "value" : 4,
+ "version" : "1.0"
},
{
"enumerant" : "Linkage",
- "value" : 5
+ "value" : 5,
+ "version" : "1.0"
},
{
"enumerant" : "Kernel",
- "value" : 6
+ "value" : 6,
+ "version" : "1.0"
},
{
"enumerant" : "Vector16",
"value" : 7,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Float16Buffer",
"value" : 8,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Float16",
- "value" : 9
+ "value" : 9,
+ "version" : "1.0"
},
{
"enumerant" : "Float64",
- "value" : 10
+ "value" : 10,
+ "version" : "1.0"
},
{
"enumerant" : "Int64",
- "value" : 11
+ "value" : 11,
+ "version" : "1.0"
},
{
"enumerant" : "Int64Atomics",
"value" : 12,
- "capabilities" : [ "Int64" ]
+ "capabilities" : [ "Int64" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageBasic",
"value" : 13,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageReadWrite",
"value" : 14,
- "capabilities" : [ "ImageBasic" ]
+ "capabilities" : [ "ImageBasic" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageMipmap",
"value" : 15,
- "capabilities" : [ "ImageBasic" ]
+ "capabilities" : [ "ImageBasic" ],
+ "version": "1.0"
},
{
"enumerant" : "Pipes",
"value" : 17,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "Groups",
"value" : 18,
- "extensions" : [ "SPV_AMD_shader_ballot" ]
+ "extensions" : [ "SPV_AMD_shader_ballot" ],
+ "version": "1.0"
},
{
"enumerant" : "DeviceEnqueue",
"value" : 19,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "LiteralSampler",
"value" : 20,
- "capabilities" : [ "Kernel" ]
+ "capabilities" : [ "Kernel" ],
+ "version": "1.0"
},
{
"enumerant" : "AtomicStorage",
"value" : 21,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Int16",
- "value" : 22
+ "value" : 22,
+ "version" : "1.0"
},
{
"enumerant" : "TessellationPointSize",
"value" : 23,
- "capabilities" : [ "Tessellation" ]
+ "capabilities" : [ "Tessellation" ],
+ "version": "1.0"
},
{
"enumerant" : "GeometryPointSize",
"value" : 24,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageGatherExtended",
"value" : 25,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageImageMultisample",
"value" : 27,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "UniformBufferArrayDynamicIndexing",
"value" : 28,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SampledImageArrayDynamicIndexing",
"value" : 29,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageBufferArrayDynamicIndexing",
"value" : 30,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageImageArrayDynamicIndexing",
"value" : 31,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "ClipDistance",
"value" : 32,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "CullDistance",
"value" : 33,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageCubeArray",
"value" : 34,
- "capabilities" : [ "SampledCubeArray" ]
+ "capabilities" : [ "SampledCubeArray" ],
+ "version": "1.0"
},
{
"enumerant" : "SampleRateShading",
"value" : 35,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageRect",
"value" : 36,
- "capabilities" : [ "SampledRect" ]
+ "capabilities" : [ "SampledRect" ],
+ "version": "1.0"
},
{
"enumerant" : "SampledRect",
"value" : 37,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "GenericPointer",
"value" : 38,
- "capabilities" : [ "Addresses" ]
+ "capabilities" : [ "Addresses" ],
+ "version": "1.0"
},
{
"enumerant" : "Int8",
- "value" : 39
+ "value" : 39,
+ "version" : "1.0"
},
{
"enumerant" : "InputAttachment",
"value" : 40,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SparseResidency",
"value" : 41,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "MinLod",
"value" : 42,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "Sampled1D",
- "value" : 43
+ "value" : 43,
+ "version" : "1.0"
},
{
"enumerant" : "Image1D",
"value" : 44,
- "capabilities" : [ "Sampled1D" ]
+ "capabilities" : [ "Sampled1D" ],
+ "version": "1.0"
},
{
"enumerant" : "SampledCubeArray",
"value" : 45,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "SampledBuffer",
- "value" : 46
+ "value" : 46,
+ "version" : "1.0"
},
{
"enumerant" : "ImageBuffer",
"value" : 47,
- "capabilities" : [ "SampledBuffer" ]
+ "capabilities" : [ "SampledBuffer" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageMSArray",
"value" : 48,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageImageExtendedFormats",
"value" : 49,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "ImageQuery",
"value" : 50,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "DerivativeControl",
"value" : 51,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "InterpolationFunction",
"value" : 52,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "TransformFeedback",
"value" : 53,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "GeometryStreams",
"value" : 54,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageImageReadWithoutFormat",
"value" : 55,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "StorageImageWriteWithoutFormat",
"value" : 56,
- "capabilities" : [ "Shader" ]
+ "capabilities" : [ "Shader" ],
+ "version": "1.0"
},
{
"enumerant" : "MultiViewport",
"value" : 57,
- "capabilities" : [ "Geometry" ]
+ "capabilities" : [ "Geometry" ],
+ "version": "1.0"
},
{
"enumerant" : "SubgroupDispatch",
@@ -14089,7 +15375,8 @@
{
"enumerant" : "CoreBuiltinsARM",
"value" : 4165,
- "extensions" : [ "SPV_ARM_core_builtins" ]
+ "extensions" : [ "SPV_ARM_core_builtins" ],
+ "version": "None"
},
{
"enumerant" : "TileImageColorReadAccessEXT",
@@ -14146,7 +15433,7 @@
{
"enumerant" : "WorkgroupMemoryExplicitLayout16BitAccessKHR",
"value" : 4430,
- "capabilities" : [ "Shader" ],
+ "capabilities" : [ "WorkgroupMemoryExplicitLayoutKHR" ],
"extensions" : [ "SPV_KHR_workgroup_memory_explicit_layout" ],
"version" : "None"
},
@@ -14335,6 +15622,12 @@
"version" : "None"
},
{
+ "enumerant" : "TextureBlockMatch2QCOM",
+ "value" : 4498,
+ "extensions" : [ "SPV_QCOM_image_processing2" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "Float16ImageAMD",
"value" : 5008,
"capabilities" : [ "Shader" ],
@@ -14383,6 +15676,19 @@
"version" : "None"
},
{
+ "enumerant" : "ShaderEnqueueAMDX",
+ "value" : 5067,
+ "capabilities" : [ "Shader" ],
+ "extensions" : [ "SPV_AMDX_shader_enqueue" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "QuadControlKHR",
+ "value" : 5087,
+ "extensions" : [ "SPV_KHR_quad_control" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "SampleMaskOverrideCoverageNV",
"value" : 5249,
"capabilities" : [ "SampleRateShading" ],
@@ -14771,6 +16077,13 @@
"version" : "1.6"
},
{
+ "enumerant" : "DisplacementMicromapNV",
+ "value" : 5380,
+ "capabilities" : [ "Shader" ],
+ "extensions" : [ "SPV_NV_displacement_micromap" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "RayTracingOpacityMicromapEXT",
"value" : 5381,
"capabilities" : [ "RayQueryKHR","RayTracingKHR" ],
@@ -14798,6 +16111,25 @@
"version" : "None"
},
{
+ "enumerant" : "AtomicFloat16VectorNV",
+ "value" : 5404,
+ "extensions" : [ "SPV_NV_shader_atomic_fp16_vector" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "RayTracingDisplacementMicromapNV",
+ "value" : 5409,
+ "capabilities" : [ "RayTracingKHR" ],
+ "extensions" : [ "SPV_NV_displacement_micromap" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "RawAccessChainsNV",
+ "value" : 5414,
+ "extensions" : [ "SPV_NV_raw_access_chains" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "SubgroupShuffleINTEL",
"value" : 5568,
"extensions" : [ "SPV_INTEL_subgroups" ],
@@ -15105,6 +16437,12 @@
"version" : "None"
},
{
+ "enumerant" : "CooperativeMatrixKHR",
+ "value" : 6022,
+ "extensions" : [ "SPV_KHR_cooperative_matrix" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "BitInstructions",
"value" : 6025,
"extensions" : [ "SPV_KHR_bit_instructions" ],
@@ -15118,6 +16456,12 @@
"version" : "None"
},
{
+ "enumerant" : "FloatControls2",
+ "value" : 6029,
+ "extensions" : [ "SPV_KHR_float_controls2" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "AtomicFloat32AddEXT",
"value" : 6033,
"extensions" : [ "SPV_EXT_shader_atomic_float_add" ],
@@ -15130,9 +16474,9 @@
"version" : "None"
},
{
- "enumerant" : "LongConstantCompositeINTEL",
+ "enumerant" : "LongCompositesINTEL",
"value" : 6089,
- "extensions" : [ "SPV_INTEL_long_constant_composite" ],
+ "extensions" : [ "SPV_INTEL_long_composites" ],
"version" : "None"
},
{
@@ -15166,6 +16510,13 @@
"version" : "None"
},
{
+ "enumerant" : "FPGAClusterAttributesV2INTEL",
+ "value" : 6150,
+ "capabilities" : [ "FPGAClusterAttributesINTEL" ],
+ "extensions" : [ "SPV_INTEL_fpga_cluster_attributes" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "FPGAKernelAttributesv2INTEL",
"value" : 6161,
"capabilities" : [ "FPGAKernelAttributesINTEL" ],
@@ -15173,6 +16524,12 @@
"version" : "None"
},
{
+ "enumerant" : "FPMaxErrorINTEL",
+ "value" : 6169,
+ "extensions" : [ "SPV_INTEL_fp_max_error" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "FPGALatencyControlINTEL",
"value" : 6171,
"extensions" : [ "SPV_INTEL_fpga_latency_control" ],
@@ -15185,10 +16542,40 @@
"version" : "None"
},
{
+ "enumerant" : "GlobalVariableHostAccessINTEL",
+ "value" : 6187,
+ "extensions": [ "SPV_INTEL_global_variable_host_access" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "GlobalVariableFPGADecorationsINTEL",
+ "value" : 6189,
+ "extensions": [ "SPV_INTEL_global_variable_fpga_decorations" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "GroupUniformArithmeticKHR",
"value" : 6400,
"extensions" : [ "SPV_KHR_uniform_group_instructions"],
"version" : "None"
+ },
+ {
+ "enumerant" : "MaskedGatherScatterINTEL",
+ "value" : 6427,
+ "extensions" : [ "SPV_INTEL_masked_gather_scatter"],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "CacheControlsINTEL",
+ "value" : 6441,
+ "extensions" : [ "SPV_INTEL_cache_controls" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "RegisterLimitsINTEL",
+ "value" : 6460,
+ "extensions" : [ "SPV_INTEL_maximum_registers" ],
+ "version" : "None"
}
]
},
@@ -15270,6 +16657,175 @@
]
},
{
+ "category" : "BitEnum",
+ "kind" : "CooperativeMatrixOperands",
+ "enumerants" : [
+ {
+ "enumerant" : "NoneKHR",
+ "value" : "0x0000",
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixASignedComponentsKHR",
+ "value" : "0x0001",
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixBSignedComponentsKHR",
+ "value" : "0x0002",
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixCSignedComponentsKHR",
+ "value" : "0x0004",
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixResultSignedComponentsKHR",
+ "value" : "0x0008",
+ "version" : "None"
+ },
+ {
+ "enumerant" : "SaturatingAccumulationKHR",
+ "value" : "0x0010",
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "CooperativeMatrixLayout",
+ "enumerants" : [
+ {
+ "enumerant" : "RowMajorKHR",
+ "value" : 0,
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ColumnMajorKHR",
+ "value" : 1,
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "CooperativeMatrixUse",
+ "enumerants" : [
+ {
+ "enumerant" : "MatrixAKHR",
+ "value" : 0,
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixBKHR",
+ "value" : 1,
+ "version" : "None"
+ },
+ {
+ "enumerant" : "MatrixAccumulatorKHR",
+ "value" : 2,
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "InitializationModeQualifier",
+ "enumerants" : [
+ {
+ "enumerant" : "InitOnDeviceReprogramINTEL",
+ "value" : 0,
+ "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "InitOnDeviceResetINTEL",
+ "value" : 1,
+ "capabilities" : [ "GlobalVariableFPGADecorationsINTEL" ],
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "LoadCacheControl",
+ "enumerants" : [
+ {
+ "enumerant" : "UncachedINTEL",
+ "value" : 0,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "CachedINTEL",
+ "value" : 1,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "StreamingINTEL",
+ "value" : 2,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "InvalidateAfterReadINTEL",
+ "value" : 3,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "ConstCachedINTEL",
+ "value" : 4,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "StoreCacheControl",
+ "enumerants" : [
+ {
+ "enumerant" : "UncachedINTEL",
+ "value" : 0,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "WriteThroughINTEL",
+ "value" : 1,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "WriteBackINTEL",
+ "value" : 2,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ },
+ {
+ "enumerant" : "StreamingINTEL",
+ "value" : 3,
+ "capabilities" : [ "CacheControlsINTEL" ],
+ "version" : "None"
+ }
+ ]
+ },
+ {
+ "category" : "ValueEnum",
+ "kind" : "NamedMaximumNumberOfRegisters",
+ "enumerants" : [
+ {
+ "enumerant" : "AutoINTEL",
+ "value" : 0,
+ "capabilities" : [ "RegisterLimitsINTEL" ],
+ "version" : "None"
+ }
+ ]
+ },
+ {
"category" : "Id",
"kind" : "IdResultType",
"doc" : "Reference to an <id> representing the result's type of the enclosing instruction"
@@ -15306,6 +16862,11 @@
},
{
"category" : "Literal",
+ "kind" : "LiteralFloat",
+ "doc" : "A float consuming one word"
+ },
+ {
+ "category" : "Literal",
"kind" : "LiteralContextDependentNumber",
"doc" : "A literal number whose size and format are determined by a previous operand in the enclosing instruction"
},
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.cs b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.cs
index 0e5d2df43..8d85cced6 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.cs
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -65,6 +65,11 @@ namespace Spv
HLSL = 5,
CPP_for_OpenCL = 6,
SYCL = 7,
+ HERO_C = 8,
+ NZSL = 9,
+ WGSL = 10,
+ Slang = 11,
+ Zig = 12,
}
public enum ExecutionModel
@@ -164,12 +169,19 @@ namespace Spv
RoundingModeRTZ = 4463,
EarlyAndLateFragmentTestsAMD = 5017,
StencilRefReplacingEXT = 5027,
+ CoalescingAMDX = 5069,
+ MaxNodeRecursionAMDX = 5071,
+ StaticNumWorkgroupsAMDX = 5072,
+ ShaderIndexAMDX = 5073,
+ MaxNumWorkgroupsAMDX = 5077,
StencilRefUnchangedFrontAMD = 5079,
StencilRefGreaterFrontAMD = 5080,
StencilRefLessFrontAMD = 5081,
StencilRefUnchangedBackAMD = 5082,
StencilRefGreaterBackAMD = 5083,
StencilRefLessBackAMD = 5084,
+ QuadDerivativesKHR = 5088,
+ RequireFullQuadsKHR = 5089,
OutputLinesEXT = 5269,
OutputLinesNV = 5269,
OutputPrimitivesEXT = 5270,
@@ -194,9 +206,14 @@ namespace Spv
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
SchedulerTargetFmaxMhzINTEL = 5903,
+ MaximallyReconvergesKHR = 6023,
+ FPFastMathDefault = 6028,
StreamingInterfaceINTEL = 6154,
RegisterMapInterfaceINTEL = 6160,
NamedBarrierCountINTEL = 6417,
+ MaximumRegistersINTEL = 6461,
+ MaximumRegistersIdINTEL = 6462,
+ NamedMaximumRegistersINTEL = 6463,
}
public enum StorageClass
@@ -215,6 +232,8 @@ namespace Spv
Image = 11,
StorageBuffer = 12,
TileImageEXT = 4172,
+ NodePayloadAMDX = 5068,
+ NodeOutputPayloadAMDX = 5076,
CallableDataKHR = 5328,
CallableDataNV = 5328,
IncomingCallableDataKHR = 5329,
@@ -352,6 +371,8 @@ namespace Spv
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
+ UnsignedIntRaw10EXT = 19,
+ UnsignedIntRaw12EXT = 20,
}
public enum ImageOperandsShift
@@ -410,8 +431,11 @@ namespace Spv
NSZ = 2,
AllowRecip = 3,
Fast = 4,
+ AllowContract = 16,
AllowContractFastINTEL = 16,
+ AllowReassoc = 17,
AllowReassocINTEL = 17,
+ AllowTransform = 18,
}
public enum FPFastMathModeMask
@@ -422,8 +446,11 @@ namespace Spv
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
+ AllowContract = 0x00010000,
AllowContractFastINTEL = 0x00010000,
+ AllowReassoc = 0x00020000,
AllowReassocINTEL = 0x00020000,
+ AllowTransform = 0x00040000,
}
public enum FPRoundingMode
@@ -514,7 +541,12 @@ namespace Spv
NoUnsignedWrap = 4470,
WeightTextureQCOM = 4487,
BlockMatchTextureQCOM = 4488,
+ BlockMatchSamplerQCOM = 4499,
ExplicitInterpAMD = 4999,
+ NodeSharesPayloadLimitsWithAMDX = 5019,
+ NodeMaxPayloadsAMDX = 5020,
+ TrackFinishWritingAMDX = 5078,
+ PayloadNodeNameAMDX = 5091,
OverrideCoverageNV = 5248,
PassthroughNV = 5250,
ViewportRelativeNV = 5252,
@@ -564,6 +596,9 @@ namespace Spv
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ StridesizeINTEL = 5883,
+ WordsizeINTEL = 5884,
+ TrueDualPortINTEL = 5885,
BurstCoalesceINTEL = 5899,
CacheSizeINTEL = 5900,
DontStaticallyCoalesceINTEL = 5901,
@@ -582,6 +617,8 @@ namespace Spv
SingleElementVectorINTEL = 6085,
VectorComputeCallableFunctionINTEL = 6087,
MediaBlockIOINTEL = 6140,
+ StallFreeINTEL = 6151,
+ FPMaxErrorDecorationINTEL = 6170,
LatencyControlLabelINTEL = 6172,
LatencyControlConstraintINTEL = 6173,
ConduitKernelArgumentINTEL = 6175,
@@ -593,6 +630,11 @@ namespace Spv
MMHostInterfaceMaxBurstINTEL = 6181,
MMHostInterfaceWaitRequestINTEL = 6182,
StableKernelArgumentINTEL = 6183,
+ HostAccessINTEL = 6188,
+ InitModeINTEL = 6190,
+ ImplementInRegisterMapINTEL = 6191,
+ CacheControlLoadINTEL = 6442,
+ CacheControlStoreINTEL = 6443,
}
public enum BuiltIn
@@ -668,6 +710,8 @@ namespace Spv
BaryCoordSmoothSampleAMD = 4997,
BaryCoordPullModelAMD = 4998,
FragStencilRefEXT = 5014,
+ CoalescedInputCountAMDX = 5021,
+ ShaderIndexAMDX = 5073,
ViewportMaskNV = 5253,
SecondaryPositionNV = 5257,
SecondaryViewportMaskNV = 5258,
@@ -721,6 +765,8 @@ namespace Spv
HitKindNV = 5333,
CurrentRayTimeNV = 5334,
HitTriangleVertexPositionsKHR = 5335,
+ HitMicroTriangleVertexPositionsNV = 5337,
+ HitMicroTriangleVertexBarycentricsNV = 5344,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -728,6 +774,8 @@ namespace Spv
SMCountNV = 5375,
WarpIDNV = 5376,
SMIDNV = 5377,
+ HitKindFrontFacingMicroTriangleNV = 5405,
+ HitKindBackFacingMicroTriangleNV = 5406,
CullMaskKHR = 6021,
}
@@ -1035,6 +1083,7 @@ namespace Spv
TextureSampleWeightedQCOM = 4484,
TextureBoxFilterQCOM = 4485,
TextureBlockMatchQCOM = 4486,
+ TextureBlockMatch2QCOM = 4498,
Float16ImageAMD = 5008,
ImageGatherBiasLodAMD = 5009,
FragmentMaskAMD = 5010,
@@ -1042,6 +1091,8 @@ namespace Spv
ImageReadWriteLodAMD = 5015,
Int64ImageEXT = 5016,
ShaderClockKHR = 5055,
+ ShaderEnqueueAMDX = 5067,
+ QuadControlKHR = 5087,
SampleMaskOverrideCoverageNV = 5249,
GeometryShaderPassthroughNV = 5251,
ShaderViewportIndexLayerEXT = 5254,
@@ -1101,10 +1152,14 @@ namespace Spv
FragmentShaderPixelInterlockEXT = 5378,
DemoteToHelperInvocation = 5379,
DemoteToHelperInvocationEXT = 5379,
+ DisplacementMicromapNV = 5380,
RayTracingOpacityMicromapEXT = 5381,
ShaderInvocationReorderNV = 5383,
BindlessTextureNV = 5390,
RayQueryPositionFetchKHR = 5391,
+ AtomicFloat16VectorNV = 5404,
+ RayTracingDisplacementMicromapNV = 5409,
+ RawAccessChainsNV = 5414,
SubgroupShuffleINTEL = 5568,
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
@@ -1156,20 +1211,29 @@ namespace Spv
DotProduct = 6019,
DotProductKHR = 6019,
RayCullMaskKHR = 6020,
+ CooperativeMatrixKHR = 6022,
BitInstructions = 6025,
GroupNonUniformRotateKHR = 6026,
+ FloatControls2 = 6029,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
- LongConstantCompositeINTEL = 6089,
+ LongCompositesINTEL = 6089,
OptNoneINTEL = 6094,
AtomicFloat16AddEXT = 6095,
DebugInfoModuleINTEL = 6114,
BFloat16ConversionINTEL = 6115,
SplitBarrierINTEL = 6141,
+ FPGAClusterAttributesV2INTEL = 6150,
FPGAKernelAttributesv2INTEL = 6161,
+ FPMaxErrorINTEL = 6169,
FPGALatencyControlINTEL = 6171,
FPGAArgumentInterfacesINTEL = 6174,
+ GlobalVariableHostAccessINTEL = 6187,
+ GlobalVariableFPGADecorationsINTEL = 6189,
GroupUniformArithmeticKHR = 6400,
+ MaskedGatherScatterINTEL = 6427,
+ CacheControlsINTEL = 6441,
+ RegisterLimitsINTEL = 6460,
}
public enum RayFlagsShift
@@ -1277,6 +1341,87 @@ namespace Spv
PackedVectorFormat4x8BitKHR = 0,
}
+ public enum CooperativeMatrixOperandsShift
+ {
+ MatrixASignedComponentsKHR = 0,
+ MatrixBSignedComponentsKHR = 1,
+ MatrixCSignedComponentsKHR = 2,
+ MatrixResultSignedComponentsKHR = 3,
+ SaturatingAccumulationKHR = 4,
+ }
+
+ public enum CooperativeMatrixOperandsMask
+ {
+ MaskNone = 0,
+ MatrixASignedComponentsKHR = 0x00000001,
+ MatrixBSignedComponentsKHR = 0x00000002,
+ MatrixCSignedComponentsKHR = 0x00000004,
+ MatrixResultSignedComponentsKHR = 0x00000008,
+ SaturatingAccumulationKHR = 0x00000010,
+ }
+
+ public enum CooperativeMatrixLayout
+ {
+ RowMajorKHR = 0,
+ ColumnMajorKHR = 1,
+ }
+
+ public enum CooperativeMatrixUse
+ {
+ MatrixAKHR = 0,
+ MatrixBKHR = 1,
+ MatrixAccumulatorKHR = 2,
+ }
+
+ public enum InitializationModeQualifier
+ {
+ InitOnDeviceReprogramINTEL = 0,
+ InitOnDeviceResetINTEL = 1,
+ }
+
+ public enum HostAccessQualifier
+ {
+ NoneINTEL = 0,
+ ReadINTEL = 1,
+ WriteINTEL = 2,
+ ReadWriteINTEL = 3,
+ }
+
+ public enum LoadCacheControl
+ {
+ UncachedINTEL = 0,
+ CachedINTEL = 1,
+ StreamingINTEL = 2,
+ InvalidateAfterReadINTEL = 3,
+ ConstCachedINTEL = 4,
+ }
+
+ public enum StoreCacheControl
+ {
+ UncachedINTEL = 0,
+ WriteThroughINTEL = 1,
+ WriteBackINTEL = 2,
+ StreamingINTEL = 3,
+ }
+
+ public enum NamedMaximumNumberOfRegisters
+ {
+ AutoINTEL = 0,
+ }
+
+ public enum RawAccessChainOperandsShift
+ {
+ RobustnessPerComponentNV = 0,
+ RobustnessPerElementNV = 1,
+ }
+
+ public enum RawAccessChainOperandsMask
+ {
+ MaskNone = 0,
+ RobustnessPerComponentNV = 0x00000001,
+ RobustnessPerElementNV = 0x00000002,
+ }
+
public enum Op
{
OpNop = 0,
@@ -1651,6 +1796,11 @@ namespace Spv
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1662,6 +1812,10 @@ namespace Spv
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1673,6 +1827,11 @@ namespace Spv
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1711,6 +1870,8 @@ namespace Spv
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1739,6 +1900,7 @@ namespace Spv
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1980,6 +2142,7 @@ namespace Spv
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1992,6 +2155,8 @@ namespace Spv
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
}
}
}
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.h b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.h
index b8de1b846..e544a853d 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.h
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.h
@@ -1,5 +1,5 @@
/*
-** Copyright (c) 2014-2020 The Khronos Group Inc.
+** Copyright (c) 2014-2024 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and/or associated documentation files (the "Materials"),
@@ -73,6 +73,11 @@ typedef enum SpvSourceLanguage_ {
SpvSourceLanguageHLSL = 5,
SpvSourceLanguageCPP_for_OpenCL = 6,
SpvSourceLanguageSYCL = 7,
+ SpvSourceLanguageHERO_C = 8,
+ SpvSourceLanguageNZSL = 9,
+ SpvSourceLanguageWGSL = 10,
+ SpvSourceLanguageSlang = 11,
+ SpvSourceLanguageZig = 12,
SpvSourceLanguageMax = 0x7fffffff,
} SpvSourceLanguage;
@@ -172,12 +177,19 @@ typedef enum SpvExecutionMode_ {
SpvExecutionModeRoundingModeRTZ = 4463,
SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017,
SpvExecutionModeStencilRefReplacingEXT = 5027,
+ SpvExecutionModeCoalescingAMDX = 5069,
+ SpvExecutionModeMaxNodeRecursionAMDX = 5071,
+ SpvExecutionModeStaticNumWorkgroupsAMDX = 5072,
+ SpvExecutionModeShaderIndexAMDX = 5073,
+ SpvExecutionModeMaxNumWorkgroupsAMDX = 5077,
SpvExecutionModeStencilRefUnchangedFrontAMD = 5079,
SpvExecutionModeStencilRefGreaterFrontAMD = 5080,
SpvExecutionModeStencilRefLessFrontAMD = 5081,
SpvExecutionModeStencilRefUnchangedBackAMD = 5082,
SpvExecutionModeStencilRefGreaterBackAMD = 5083,
SpvExecutionModeStencilRefLessBackAMD = 5084,
+ SpvExecutionModeQuadDerivativesKHR = 5088,
+ SpvExecutionModeRequireFullQuadsKHR = 5089,
SpvExecutionModeOutputLinesEXT = 5269,
SpvExecutionModeOutputLinesNV = 5269,
SpvExecutionModeOutputPrimitivesEXT = 5270,
@@ -202,9 +214,14 @@ typedef enum SpvExecutionMode_ {
SpvExecutionModeNoGlobalOffsetINTEL = 5895,
SpvExecutionModeNumSIMDWorkitemsINTEL = 5896,
SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
+ SpvExecutionModeMaximallyReconvergesKHR = 6023,
+ SpvExecutionModeFPFastMathDefault = 6028,
SpvExecutionModeStreamingInterfaceINTEL = 6154,
SpvExecutionModeRegisterMapInterfaceINTEL = 6160,
SpvExecutionModeNamedBarrierCountINTEL = 6417,
+ SpvExecutionModeMaximumRegistersINTEL = 6461,
+ SpvExecutionModeMaximumRegistersIdINTEL = 6462,
+ SpvExecutionModeNamedMaximumRegistersINTEL = 6463,
SpvExecutionModeMax = 0x7fffffff,
} SpvExecutionMode;
@@ -223,6 +240,8 @@ typedef enum SpvStorageClass_ {
SpvStorageClassImage = 11,
SpvStorageClassStorageBuffer = 12,
SpvStorageClassTileImageEXT = 4172,
+ SpvStorageClassNodePayloadAMDX = 5068,
+ SpvStorageClassNodeOutputPayloadAMDX = 5076,
SpvStorageClassCallableDataKHR = 5328,
SpvStorageClassCallableDataNV = 5328,
SpvStorageClassIncomingCallableDataKHR = 5329,
@@ -360,6 +379,8 @@ typedef enum SpvImageChannelDataType_ {
SpvImageChannelDataTypeFloat = 14,
SpvImageChannelDataTypeUnormInt24 = 15,
SpvImageChannelDataTypeUnormInt101010_2 = 16,
+ SpvImageChannelDataTypeUnsignedIntRaw10EXT = 19,
+ SpvImageChannelDataTypeUnsignedIntRaw12EXT = 20,
SpvImageChannelDataTypeMax = 0x7fffffff,
} SpvImageChannelDataType;
@@ -417,8 +438,11 @@ typedef enum SpvFPFastMathModeShift_ {
SpvFPFastMathModeNSZShift = 2,
SpvFPFastMathModeAllowRecipShift = 3,
SpvFPFastMathModeFastShift = 4,
+ SpvFPFastMathModeAllowContractShift = 16,
SpvFPFastMathModeAllowContractFastINTELShift = 16,
+ SpvFPFastMathModeAllowReassocShift = 17,
SpvFPFastMathModeAllowReassocINTELShift = 17,
+ SpvFPFastMathModeAllowTransformShift = 18,
SpvFPFastMathModeMax = 0x7fffffff,
} SpvFPFastMathModeShift;
@@ -429,8 +453,11 @@ typedef enum SpvFPFastMathModeMask_ {
SpvFPFastMathModeNSZMask = 0x00000004,
SpvFPFastMathModeAllowRecipMask = 0x00000008,
SpvFPFastMathModeFastMask = 0x00000010,
+ SpvFPFastMathModeAllowContractMask = 0x00010000,
SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000,
+ SpvFPFastMathModeAllowReassocMask = 0x00020000,
SpvFPFastMathModeAllowReassocINTELMask = 0x00020000,
+ SpvFPFastMathModeAllowTransformMask = 0x00040000,
} SpvFPFastMathModeMask;
typedef enum SpvFPRoundingMode_ {
@@ -520,7 +547,12 @@ typedef enum SpvDecoration_ {
SpvDecorationNoUnsignedWrap = 4470,
SpvDecorationWeightTextureQCOM = 4487,
SpvDecorationBlockMatchTextureQCOM = 4488,
+ SpvDecorationBlockMatchSamplerQCOM = 4499,
SpvDecorationExplicitInterpAMD = 4999,
+ SpvDecorationNodeSharesPayloadLimitsWithAMDX = 5019,
+ SpvDecorationNodeMaxPayloadsAMDX = 5020,
+ SpvDecorationTrackFinishWritingAMDX = 5078,
+ SpvDecorationPayloadNodeNameAMDX = 5091,
SpvDecorationOverrideCoverageNV = 5248,
SpvDecorationPassthroughNV = 5250,
SpvDecorationViewportRelativeNV = 5252,
@@ -570,6 +602,9 @@ typedef enum SpvDecoration_ {
SpvDecorationMergeINTEL = 5834,
SpvDecorationBankBitsINTEL = 5835,
SpvDecorationForcePow2DepthINTEL = 5836,
+ SpvDecorationStridesizeINTEL = 5883,
+ SpvDecorationWordsizeINTEL = 5884,
+ SpvDecorationTrueDualPortINTEL = 5885,
SpvDecorationBurstCoalesceINTEL = 5899,
SpvDecorationCacheSizeINTEL = 5900,
SpvDecorationDontStaticallyCoalesceINTEL = 5901,
@@ -588,6 +623,8 @@ typedef enum SpvDecoration_ {
SpvDecorationSingleElementVectorINTEL = 6085,
SpvDecorationVectorComputeCallableFunctionINTEL = 6087,
SpvDecorationMediaBlockIOINTEL = 6140,
+ SpvDecorationStallFreeINTEL = 6151,
+ SpvDecorationFPMaxErrorDecorationINTEL = 6170,
SpvDecorationLatencyControlLabelINTEL = 6172,
SpvDecorationLatencyControlConstraintINTEL = 6173,
SpvDecorationConduitKernelArgumentINTEL = 6175,
@@ -599,6 +636,11 @@ typedef enum SpvDecoration_ {
SpvDecorationMMHostInterfaceMaxBurstINTEL = 6181,
SpvDecorationMMHostInterfaceWaitRequestINTEL = 6182,
SpvDecorationStableKernelArgumentINTEL = 6183,
+ SpvDecorationHostAccessINTEL = 6188,
+ SpvDecorationInitModeINTEL = 6190,
+ SpvDecorationImplementInRegisterMapINTEL = 6191,
+ SpvDecorationCacheControlLoadINTEL = 6442,
+ SpvDecorationCacheControlStoreINTEL = 6443,
SpvDecorationMax = 0x7fffffff,
} SpvDecoration;
@@ -674,6 +716,8 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInBaryCoordSmoothSampleAMD = 4997,
SpvBuiltInBaryCoordPullModelAMD = 4998,
SpvBuiltInFragStencilRefEXT = 5014,
+ SpvBuiltInCoalescedInputCountAMDX = 5021,
+ SpvBuiltInShaderIndexAMDX = 5073,
SpvBuiltInViewportMaskNV = 5253,
SpvBuiltInSecondaryPositionNV = 5257,
SpvBuiltInSecondaryViewportMaskNV = 5258,
@@ -727,6 +771,8 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInHitKindNV = 5333,
SpvBuiltInCurrentRayTimeNV = 5334,
SpvBuiltInHitTriangleVertexPositionsKHR = 5335,
+ SpvBuiltInHitMicroTriangleVertexPositionsNV = 5337,
+ SpvBuiltInHitMicroTriangleVertexBarycentricsNV = 5344,
SpvBuiltInIncomingRayFlagsKHR = 5351,
SpvBuiltInIncomingRayFlagsNV = 5351,
SpvBuiltInRayGeometryIndexKHR = 5352,
@@ -734,6 +780,8 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInSMCountNV = 5375,
SpvBuiltInWarpIDNV = 5376,
SpvBuiltInSMIDNV = 5377,
+ SpvBuiltInHitKindFrontFacingMicroTriangleNV = 5405,
+ SpvBuiltInHitKindBackFacingMicroTriangleNV = 5406,
SpvBuiltInCullMaskKHR = 6021,
SpvBuiltInMax = 0x7fffffff,
} SpvBuiltIn;
@@ -1035,6 +1083,7 @@ typedef enum SpvCapability_ {
SpvCapabilityTextureSampleWeightedQCOM = 4484,
SpvCapabilityTextureBoxFilterQCOM = 4485,
SpvCapabilityTextureBlockMatchQCOM = 4486,
+ SpvCapabilityTextureBlockMatch2QCOM = 4498,
SpvCapabilityFloat16ImageAMD = 5008,
SpvCapabilityImageGatherBiasLodAMD = 5009,
SpvCapabilityFragmentMaskAMD = 5010,
@@ -1042,6 +1091,8 @@ typedef enum SpvCapability_ {
SpvCapabilityImageReadWriteLodAMD = 5015,
SpvCapabilityInt64ImageEXT = 5016,
SpvCapabilityShaderClockKHR = 5055,
+ SpvCapabilityShaderEnqueueAMDX = 5067,
+ SpvCapabilityQuadControlKHR = 5087,
SpvCapabilitySampleMaskOverrideCoverageNV = 5249,
SpvCapabilityGeometryShaderPassthroughNV = 5251,
SpvCapabilityShaderViewportIndexLayerEXT = 5254,
@@ -1101,10 +1152,14 @@ typedef enum SpvCapability_ {
SpvCapabilityFragmentShaderPixelInterlockEXT = 5378,
SpvCapabilityDemoteToHelperInvocation = 5379,
SpvCapabilityDemoteToHelperInvocationEXT = 5379,
+ SpvCapabilityDisplacementMicromapNV = 5380,
SpvCapabilityRayTracingOpacityMicromapEXT = 5381,
SpvCapabilityShaderInvocationReorderNV = 5383,
SpvCapabilityBindlessTextureNV = 5390,
SpvCapabilityRayQueryPositionFetchKHR = 5391,
+ SpvCapabilityAtomicFloat16VectorNV = 5404,
+ SpvCapabilityRayTracingDisplacementMicromapNV = 5409,
+ SpvCapabilityRawAccessChainsNV = 5414,
SpvCapabilitySubgroupShuffleINTEL = 5568,
SpvCapabilitySubgroupBufferBlockIOINTEL = 5569,
SpvCapabilitySubgroupImageBlockIOINTEL = 5570,
@@ -1156,20 +1211,29 @@ typedef enum SpvCapability_ {
SpvCapabilityDotProduct = 6019,
SpvCapabilityDotProductKHR = 6019,
SpvCapabilityRayCullMaskKHR = 6020,
+ SpvCapabilityCooperativeMatrixKHR = 6022,
SpvCapabilityBitInstructions = 6025,
SpvCapabilityGroupNonUniformRotateKHR = 6026,
+ SpvCapabilityFloatControls2 = 6029,
SpvCapabilityAtomicFloat32AddEXT = 6033,
SpvCapabilityAtomicFloat64AddEXT = 6034,
- SpvCapabilityLongConstantCompositeINTEL = 6089,
+ SpvCapabilityLongCompositesINTEL = 6089,
SpvCapabilityOptNoneINTEL = 6094,
SpvCapabilityAtomicFloat16AddEXT = 6095,
SpvCapabilityDebugInfoModuleINTEL = 6114,
SpvCapabilityBFloat16ConversionINTEL = 6115,
SpvCapabilitySplitBarrierINTEL = 6141,
+ SpvCapabilityFPGAClusterAttributesV2INTEL = 6150,
SpvCapabilityFPGAKernelAttributesv2INTEL = 6161,
+ SpvCapabilityFPMaxErrorINTEL = 6169,
SpvCapabilityFPGALatencyControlINTEL = 6171,
SpvCapabilityFPGAArgumentInterfacesINTEL = 6174,
+ SpvCapabilityGlobalVariableHostAccessINTEL = 6187,
+ SpvCapabilityGlobalVariableFPGADecorationsINTEL = 6189,
SpvCapabilityGroupUniformArithmeticKHR = 6400,
+ SpvCapabilityMaskedGatherScatterINTEL = 6427,
+ SpvCapabilityCacheControlsINTEL = 6441,
+ SpvCapabilityRegisterLimitsINTEL = 6460,
SpvCapabilityMax = 0x7fffffff,
} SpvCapability;
@@ -1276,6 +1340,85 @@ typedef enum SpvPackedVectorFormat_ {
SpvPackedVectorFormatMax = 0x7fffffff,
} SpvPackedVectorFormat;
+typedef enum SpvCooperativeMatrixOperandsShift_ {
+ SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0,
+ SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1,
+ SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2,
+ SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3,
+ SpvCooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4,
+ SpvCooperativeMatrixOperandsMax = 0x7fffffff,
+} SpvCooperativeMatrixOperandsShift;
+
+typedef enum SpvCooperativeMatrixOperandsMask_ {
+ SpvCooperativeMatrixOperandsMaskNone = 0,
+ SpvCooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001,
+ SpvCooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002,
+ SpvCooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004,
+ SpvCooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008,
+ SpvCooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010,
+} SpvCooperativeMatrixOperandsMask;
+
+typedef enum SpvCooperativeMatrixLayout_ {
+ SpvCooperativeMatrixLayoutRowMajorKHR = 0,
+ SpvCooperativeMatrixLayoutColumnMajorKHR = 1,
+ SpvCooperativeMatrixLayoutMax = 0x7fffffff,
+} SpvCooperativeMatrixLayout;
+
+typedef enum SpvCooperativeMatrixUse_ {
+ SpvCooperativeMatrixUseMatrixAKHR = 0,
+ SpvCooperativeMatrixUseMatrixBKHR = 1,
+ SpvCooperativeMatrixUseMatrixAccumulatorKHR = 2,
+ SpvCooperativeMatrixUseMax = 0x7fffffff,
+} SpvCooperativeMatrixUse;
+
+typedef enum SpvInitializationModeQualifier_ {
+ SpvInitializationModeQualifierInitOnDeviceReprogramINTEL = 0,
+ SpvInitializationModeQualifierInitOnDeviceResetINTEL = 1,
+ SpvInitializationModeQualifierMax = 0x7fffffff,
+} SpvInitializationModeQualifier;
+
+typedef enum SpvHostAccessQualifier_ {
+ SpvHostAccessQualifierNoneINTEL = 0,
+ SpvHostAccessQualifierReadINTEL = 1,
+ SpvHostAccessQualifierWriteINTEL = 2,
+ SpvHostAccessQualifierReadWriteINTEL = 3,
+ SpvHostAccessQualifierMax = 0x7fffffff,
+} SpvHostAccessQualifier;
+
+typedef enum SpvLoadCacheControl_ {
+ SpvLoadCacheControlUncachedINTEL = 0,
+ SpvLoadCacheControlCachedINTEL = 1,
+ SpvLoadCacheControlStreamingINTEL = 2,
+ SpvLoadCacheControlInvalidateAfterReadINTEL = 3,
+ SpvLoadCacheControlConstCachedINTEL = 4,
+ SpvLoadCacheControlMax = 0x7fffffff,
+} SpvLoadCacheControl;
+
+typedef enum SpvStoreCacheControl_ {
+ SpvStoreCacheControlUncachedINTEL = 0,
+ SpvStoreCacheControlWriteThroughINTEL = 1,
+ SpvStoreCacheControlWriteBackINTEL = 2,
+ SpvStoreCacheControlStreamingINTEL = 3,
+ SpvStoreCacheControlMax = 0x7fffffff,
+} SpvStoreCacheControl;
+
+typedef enum SpvNamedMaximumNumberOfRegisters_ {
+ SpvNamedMaximumNumberOfRegistersAutoINTEL = 0,
+ SpvNamedMaximumNumberOfRegistersMax = 0x7fffffff,
+} SpvNamedMaximumNumberOfRegisters;
+
+typedef enum SpvRawAccessChainOperandsShift_ {
+ SpvRawAccessChainOperandsRobustnessPerComponentNVShift = 0,
+ SpvRawAccessChainOperandsRobustnessPerElementNVShift = 1,
+ SpvRawAccessChainOperandsMax = 0x7fffffff,
+} SpvRawAccessChainOperandsShift;
+
+typedef enum SpvRawAccessChainOperandsMask_ {
+ SpvRawAccessChainOperandsMaskNone = 0,
+ SpvRawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001,
+ SpvRawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002,
+} SpvRawAccessChainOperandsMask;
+
typedef enum SpvOp_ {
SpvOpNop = 0,
SpvOpUndef = 1,
@@ -1649,6 +1792,11 @@ typedef enum SpvOp_ {
SpvOpUDotAccSatKHR = 4454,
SpvOpSUDotAccSat = 4455,
SpvOpSUDotAccSatKHR = 4455,
+ SpvOpTypeCooperativeMatrixKHR = 4456,
+ SpvOpCooperativeMatrixLoadKHR = 4457,
+ SpvOpCooperativeMatrixStoreKHR = 4458,
+ SpvOpCooperativeMatrixMulAddKHR = 4459,
+ SpvOpCooperativeMatrixLengthKHR = 4460,
SpvOpTypeRayQueryKHR = 4472,
SpvOpRayQueryInitializeKHR = 4473,
SpvOpRayQueryTerminateKHR = 4474,
@@ -1660,6 +1808,10 @@ typedef enum SpvOp_ {
SpvOpImageBoxFilterQCOM = 4481,
SpvOpImageBlockMatchSSDQCOM = 4482,
SpvOpImageBlockMatchSADQCOM = 4483,
+ SpvOpImageBlockMatchWindowSSDQCOM = 4500,
+ SpvOpImageBlockMatchWindowSADQCOM = 4501,
+ SpvOpImageBlockMatchGatherSSDQCOM = 4502,
+ SpvOpImageBlockMatchGatherSADQCOM = 4503,
SpvOpGroupIAddNonUniformAMD = 5000,
SpvOpGroupFAddNonUniformAMD = 5001,
SpvOpGroupFMinNonUniformAMD = 5002,
@@ -1671,6 +1823,11 @@ typedef enum SpvOp_ {
SpvOpFragmentMaskFetchAMD = 5011,
SpvOpFragmentFetchAMD = 5012,
SpvOpReadClockKHR = 5056,
+ SpvOpFinalizeNodePayloadsAMDX = 5075,
+ SpvOpFinishWritingNodePayloadAMDX = 5078,
+ SpvOpInitializeNodePayloadsAMDX = 5090,
+ SpvOpGroupNonUniformQuadAllKHR = 5110,
+ SpvOpGroupNonUniformQuadAnyKHR = 5111,
SpvOpHitObjectRecordHitMotionNV = 5249,
SpvOpHitObjectRecordHitWithIndexMotionNV = 5250,
SpvOpHitObjectRecordMissMotionNV = 5251,
@@ -1709,6 +1866,8 @@ typedef enum SpvOp_ {
SpvOpSetMeshOutputsEXT = 5295,
SpvOpGroupNonUniformPartitionNV = 5296,
SpvOpWritePackedPrimitiveIndices4x8NV = 5299,
+ SpvOpFetchMicroTriangleVertexPositionNV = 5300,
+ SpvOpFetchMicroTriangleVertexBarycentricNV = 5301,
SpvOpReportIntersectionKHR = 5334,
SpvOpReportIntersectionNV = 5334,
SpvOpIgnoreIntersectionNV = 5335,
@@ -1737,6 +1896,7 @@ typedef enum SpvOp_ {
SpvOpConvertUToSampledImageNV = 5395,
SpvOpConvertSampledImageToUNV = 5396,
SpvOpSamplerImageAddressingModeNV = 5397,
+ SpvOpRawAccessChainNV = 5398,
SpvOpSubgroupShuffleINTEL = 5571,
SpvOpSubgroupShuffleDownINTEL = 5572,
SpvOpSubgroupShuffleUpINTEL = 5573,
@@ -1978,6 +2138,7 @@ typedef enum SpvOp_ {
SpvOpTypeStructContinuedINTEL = 6090,
SpvOpConstantCompositeContinuedINTEL = 6091,
SpvOpSpecConstantCompositeContinuedINTEL = 6092,
+ SpvOpCompositeConstructContinuedINTEL = 6096,
SpvOpConvertFToBF16INTEL = 6116,
SpvOpConvertBF16ToFINTEL = 6117,
SpvOpControlBarrierArriveINTEL = 6142,
@@ -1990,6 +2151,8 @@ typedef enum SpvOp_ {
SpvOpGroupLogicalAndKHR = 6406,
SpvOpGroupLogicalOrKHR = 6407,
SpvOpGroupLogicalXorKHR = 6408,
+ SpvOpMaskedGatherINTEL = 6428,
+ SpvOpMaskedScatterINTEL = 6429,
SpvOpMax = 0x7fffffff,
} SpvOp;
@@ -2367,6 +2530,11 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break;
case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break;
case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
+ case SpvOpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break;
+ case SpvOpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
@@ -2378,6 +2546,10 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case SpvOpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@@ -2389,6 +2561,11 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case SpvOpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break;
+ case SpvOpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case SpvOpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break;
@@ -2427,6 +2604,8 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break;
case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;
case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break;
+ case SpvOpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break;
case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;
case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
@@ -2452,6 +2631,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;
case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;
case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpRawAccessChainNV: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2691,6 +2871,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+ case SpvOpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break;
case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
@@ -2703,6 +2884,8 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break;
+ case SpvOpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp
index 421d68432..a383739fe 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -69,6 +69,11 @@ enum SourceLanguage {
SourceLanguageHLSL = 5,
SourceLanguageCPP_for_OpenCL = 6,
SourceLanguageSYCL = 7,
+ SourceLanguageHERO_C = 8,
+ SourceLanguageNZSL = 9,
+ SourceLanguageWGSL = 10,
+ SourceLanguageSlang = 11,
+ SourceLanguageZig = 12,
SourceLanguageMax = 0x7fffffff,
};
@@ -168,12 +173,19 @@ enum ExecutionMode {
ExecutionModeRoundingModeRTZ = 4463,
ExecutionModeEarlyAndLateFragmentTestsAMD = 5017,
ExecutionModeStencilRefReplacingEXT = 5027,
+ ExecutionModeCoalescingAMDX = 5069,
+ ExecutionModeMaxNodeRecursionAMDX = 5071,
+ ExecutionModeStaticNumWorkgroupsAMDX = 5072,
+ ExecutionModeShaderIndexAMDX = 5073,
+ ExecutionModeMaxNumWorkgroupsAMDX = 5077,
ExecutionModeStencilRefUnchangedFrontAMD = 5079,
ExecutionModeStencilRefGreaterFrontAMD = 5080,
ExecutionModeStencilRefLessFrontAMD = 5081,
ExecutionModeStencilRefUnchangedBackAMD = 5082,
ExecutionModeStencilRefGreaterBackAMD = 5083,
ExecutionModeStencilRefLessBackAMD = 5084,
+ ExecutionModeQuadDerivativesKHR = 5088,
+ ExecutionModeRequireFullQuadsKHR = 5089,
ExecutionModeOutputLinesEXT = 5269,
ExecutionModeOutputLinesNV = 5269,
ExecutionModeOutputPrimitivesEXT = 5270,
@@ -198,9 +210,14 @@ enum ExecutionMode {
ExecutionModeNoGlobalOffsetINTEL = 5895,
ExecutionModeNumSIMDWorkitemsINTEL = 5896,
ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903,
+ ExecutionModeMaximallyReconvergesKHR = 6023,
+ ExecutionModeFPFastMathDefault = 6028,
ExecutionModeStreamingInterfaceINTEL = 6154,
ExecutionModeRegisterMapInterfaceINTEL = 6160,
ExecutionModeNamedBarrierCountINTEL = 6417,
+ ExecutionModeMaximumRegistersINTEL = 6461,
+ ExecutionModeMaximumRegistersIdINTEL = 6462,
+ ExecutionModeNamedMaximumRegistersINTEL = 6463,
ExecutionModeMax = 0x7fffffff,
};
@@ -219,6 +236,8 @@ enum StorageClass {
StorageClassImage = 11,
StorageClassStorageBuffer = 12,
StorageClassTileImageEXT = 4172,
+ StorageClassNodePayloadAMDX = 5068,
+ StorageClassNodeOutputPayloadAMDX = 5076,
StorageClassCallableDataKHR = 5328,
StorageClassCallableDataNV = 5328,
StorageClassIncomingCallableDataKHR = 5329,
@@ -356,6 +375,8 @@ enum ImageChannelDataType {
ImageChannelDataTypeFloat = 14,
ImageChannelDataTypeUnormInt24 = 15,
ImageChannelDataTypeUnormInt101010_2 = 16,
+ ImageChannelDataTypeUnsignedIntRaw10EXT = 19,
+ ImageChannelDataTypeUnsignedIntRaw12EXT = 20,
ImageChannelDataTypeMax = 0x7fffffff,
};
@@ -413,8 +434,11 @@ enum FPFastMathModeShift {
FPFastMathModeNSZShift = 2,
FPFastMathModeAllowRecipShift = 3,
FPFastMathModeFastShift = 4,
+ FPFastMathModeAllowContractShift = 16,
FPFastMathModeAllowContractFastINTELShift = 16,
+ FPFastMathModeAllowReassocShift = 17,
FPFastMathModeAllowReassocINTELShift = 17,
+ FPFastMathModeAllowTransformShift = 18,
FPFastMathModeMax = 0x7fffffff,
};
@@ -425,8 +449,11 @@ enum FPFastMathModeMask {
FPFastMathModeNSZMask = 0x00000004,
FPFastMathModeAllowRecipMask = 0x00000008,
FPFastMathModeFastMask = 0x00000010,
+ FPFastMathModeAllowContractMask = 0x00010000,
FPFastMathModeAllowContractFastINTELMask = 0x00010000,
+ FPFastMathModeAllowReassocMask = 0x00020000,
FPFastMathModeAllowReassocINTELMask = 0x00020000,
+ FPFastMathModeAllowTransformMask = 0x00040000,
};
enum FPRoundingMode {
@@ -516,7 +543,12 @@ enum Decoration {
DecorationNoUnsignedWrap = 4470,
DecorationWeightTextureQCOM = 4487,
DecorationBlockMatchTextureQCOM = 4488,
+ DecorationBlockMatchSamplerQCOM = 4499,
DecorationExplicitInterpAMD = 4999,
+ DecorationNodeSharesPayloadLimitsWithAMDX = 5019,
+ DecorationNodeMaxPayloadsAMDX = 5020,
+ DecorationTrackFinishWritingAMDX = 5078,
+ DecorationPayloadNodeNameAMDX = 5091,
DecorationOverrideCoverageNV = 5248,
DecorationPassthroughNV = 5250,
DecorationViewportRelativeNV = 5252,
@@ -566,6 +598,9 @@ enum Decoration {
DecorationMergeINTEL = 5834,
DecorationBankBitsINTEL = 5835,
DecorationForcePow2DepthINTEL = 5836,
+ DecorationStridesizeINTEL = 5883,
+ DecorationWordsizeINTEL = 5884,
+ DecorationTrueDualPortINTEL = 5885,
DecorationBurstCoalesceINTEL = 5899,
DecorationCacheSizeINTEL = 5900,
DecorationDontStaticallyCoalesceINTEL = 5901,
@@ -584,6 +619,8 @@ enum Decoration {
DecorationSingleElementVectorINTEL = 6085,
DecorationVectorComputeCallableFunctionINTEL = 6087,
DecorationMediaBlockIOINTEL = 6140,
+ DecorationStallFreeINTEL = 6151,
+ DecorationFPMaxErrorDecorationINTEL = 6170,
DecorationLatencyControlLabelINTEL = 6172,
DecorationLatencyControlConstraintINTEL = 6173,
DecorationConduitKernelArgumentINTEL = 6175,
@@ -595,6 +632,11 @@ enum Decoration {
DecorationMMHostInterfaceMaxBurstINTEL = 6181,
DecorationMMHostInterfaceWaitRequestINTEL = 6182,
DecorationStableKernelArgumentINTEL = 6183,
+ DecorationHostAccessINTEL = 6188,
+ DecorationInitModeINTEL = 6190,
+ DecorationImplementInRegisterMapINTEL = 6191,
+ DecorationCacheControlLoadINTEL = 6442,
+ DecorationCacheControlStoreINTEL = 6443,
DecorationMax = 0x7fffffff,
};
@@ -670,6 +712,8 @@ enum BuiltIn {
BuiltInBaryCoordSmoothSampleAMD = 4997,
BuiltInBaryCoordPullModelAMD = 4998,
BuiltInFragStencilRefEXT = 5014,
+ BuiltInCoalescedInputCountAMDX = 5021,
+ BuiltInShaderIndexAMDX = 5073,
BuiltInViewportMaskNV = 5253,
BuiltInSecondaryPositionNV = 5257,
BuiltInSecondaryViewportMaskNV = 5258,
@@ -723,6 +767,8 @@ enum BuiltIn {
BuiltInHitKindNV = 5333,
BuiltInCurrentRayTimeNV = 5334,
BuiltInHitTriangleVertexPositionsKHR = 5335,
+ BuiltInHitMicroTriangleVertexPositionsNV = 5337,
+ BuiltInHitMicroTriangleVertexBarycentricsNV = 5344,
BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352,
@@ -730,6 +776,8 @@ enum BuiltIn {
BuiltInSMCountNV = 5375,
BuiltInWarpIDNV = 5376,
BuiltInSMIDNV = 5377,
+ BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
+ BuiltInHitKindBackFacingMicroTriangleNV = 5406,
BuiltInCullMaskKHR = 6021,
BuiltInMax = 0x7fffffff,
};
@@ -1031,6 +1079,7 @@ enum Capability {
CapabilityTextureSampleWeightedQCOM = 4484,
CapabilityTextureBoxFilterQCOM = 4485,
CapabilityTextureBlockMatchQCOM = 4486,
+ CapabilityTextureBlockMatch2QCOM = 4498,
CapabilityFloat16ImageAMD = 5008,
CapabilityImageGatherBiasLodAMD = 5009,
CapabilityFragmentMaskAMD = 5010,
@@ -1038,6 +1087,8 @@ enum Capability {
CapabilityImageReadWriteLodAMD = 5015,
CapabilityInt64ImageEXT = 5016,
CapabilityShaderClockKHR = 5055,
+ CapabilityShaderEnqueueAMDX = 5067,
+ CapabilityQuadControlKHR = 5087,
CapabilitySampleMaskOverrideCoverageNV = 5249,
CapabilityGeometryShaderPassthroughNV = 5251,
CapabilityShaderViewportIndexLayerEXT = 5254,
@@ -1097,10 +1148,14 @@ enum Capability {
CapabilityFragmentShaderPixelInterlockEXT = 5378,
CapabilityDemoteToHelperInvocation = 5379,
CapabilityDemoteToHelperInvocationEXT = 5379,
+ CapabilityDisplacementMicromapNV = 5380,
CapabilityRayTracingOpacityMicromapEXT = 5381,
CapabilityShaderInvocationReorderNV = 5383,
CapabilityBindlessTextureNV = 5390,
CapabilityRayQueryPositionFetchKHR = 5391,
+ CapabilityAtomicFloat16VectorNV = 5404,
+ CapabilityRayTracingDisplacementMicromapNV = 5409,
+ CapabilityRawAccessChainsNV = 5414,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
@@ -1152,20 +1207,29 @@ enum Capability {
CapabilityDotProduct = 6019,
CapabilityDotProductKHR = 6019,
CapabilityRayCullMaskKHR = 6020,
+ CapabilityCooperativeMatrixKHR = 6022,
CapabilityBitInstructions = 6025,
CapabilityGroupNonUniformRotateKHR = 6026,
+ CapabilityFloatControls2 = 6029,
CapabilityAtomicFloat32AddEXT = 6033,
CapabilityAtomicFloat64AddEXT = 6034,
- CapabilityLongConstantCompositeINTEL = 6089,
+ CapabilityLongCompositesINTEL = 6089,
CapabilityOptNoneINTEL = 6094,
CapabilityAtomicFloat16AddEXT = 6095,
CapabilityDebugInfoModuleINTEL = 6114,
CapabilityBFloat16ConversionINTEL = 6115,
CapabilitySplitBarrierINTEL = 6141,
+ CapabilityFPGAClusterAttributesV2INTEL = 6150,
CapabilityFPGAKernelAttributesv2INTEL = 6161,
+ CapabilityFPMaxErrorINTEL = 6169,
CapabilityFPGALatencyControlINTEL = 6171,
CapabilityFPGAArgumentInterfacesINTEL = 6174,
+ CapabilityGlobalVariableHostAccessINTEL = 6187,
+ CapabilityGlobalVariableFPGADecorationsINTEL = 6189,
CapabilityGroupUniformArithmeticKHR = 6400,
+ CapabilityMaskedGatherScatterINTEL = 6427,
+ CapabilityCacheControlsINTEL = 6441,
+ CapabilityRegisterLimitsINTEL = 6460,
CapabilityMax = 0x7fffffff,
};
@@ -1272,6 +1336,85 @@ enum PackedVectorFormat {
PackedVectorFormatMax = 0x7fffffff,
};
+enum CooperativeMatrixOperandsShift {
+ CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0,
+ CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1,
+ CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2,
+ CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3,
+ CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4,
+ CooperativeMatrixOperandsMax = 0x7fffffff,
+};
+
+enum CooperativeMatrixOperandsMask {
+ CooperativeMatrixOperandsMaskNone = 0,
+ CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001,
+ CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002,
+ CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004,
+ CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008,
+ CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010,
+};
+
+enum CooperativeMatrixLayout {
+ CooperativeMatrixLayoutRowMajorKHR = 0,
+ CooperativeMatrixLayoutColumnMajorKHR = 1,
+ CooperativeMatrixLayoutMax = 0x7fffffff,
+};
+
+enum CooperativeMatrixUse {
+ CooperativeMatrixUseMatrixAKHR = 0,
+ CooperativeMatrixUseMatrixBKHR = 1,
+ CooperativeMatrixUseMatrixAccumulatorKHR = 2,
+ CooperativeMatrixUseMax = 0x7fffffff,
+};
+
+enum InitializationModeQualifier {
+ InitializationModeQualifierInitOnDeviceReprogramINTEL = 0,
+ InitializationModeQualifierInitOnDeviceResetINTEL = 1,
+ InitializationModeQualifierMax = 0x7fffffff,
+};
+
+enum HostAccessQualifier {
+ HostAccessQualifierNoneINTEL = 0,
+ HostAccessQualifierReadINTEL = 1,
+ HostAccessQualifierWriteINTEL = 2,
+ HostAccessQualifierReadWriteINTEL = 3,
+ HostAccessQualifierMax = 0x7fffffff,
+};
+
+enum LoadCacheControl {
+ LoadCacheControlUncachedINTEL = 0,
+ LoadCacheControlCachedINTEL = 1,
+ LoadCacheControlStreamingINTEL = 2,
+ LoadCacheControlInvalidateAfterReadINTEL = 3,
+ LoadCacheControlConstCachedINTEL = 4,
+ LoadCacheControlMax = 0x7fffffff,
+};
+
+enum StoreCacheControl {
+ StoreCacheControlUncachedINTEL = 0,
+ StoreCacheControlWriteThroughINTEL = 1,
+ StoreCacheControlWriteBackINTEL = 2,
+ StoreCacheControlStreamingINTEL = 3,
+ StoreCacheControlMax = 0x7fffffff,
+};
+
+enum NamedMaximumNumberOfRegisters {
+ NamedMaximumNumberOfRegistersAutoINTEL = 0,
+ NamedMaximumNumberOfRegistersMax = 0x7fffffff,
+};
+
+enum RawAccessChainOperandsShift {
+ RawAccessChainOperandsRobustnessPerComponentNVShift = 0,
+ RawAccessChainOperandsRobustnessPerElementNVShift = 1,
+ RawAccessChainOperandsMax = 0x7fffffff,
+};
+
+enum RawAccessChainOperandsMask {
+ RawAccessChainOperandsMaskNone = 0,
+ RawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001,
+ RawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002,
+};
+
enum Op {
OpNop = 0,
OpUndef = 1,
@@ -1645,6 +1788,11 @@ enum Op {
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1656,6 +1804,10 @@ enum Op {
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1667,6 +1819,11 @@ enum Op {
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1705,6 +1862,8 @@ enum Op {
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1733,6 +1892,7 @@ enum Op {
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1974,6 +2134,7 @@ enum Op {
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1986,6 +2147,8 @@ enum Op {
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
OpMax = 0x7fffffff,
};
@@ -2363,6 +2526,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSDotAccSat: *hasResult = true; *hasResultType = true; break;
case OpUDotAccSat: *hasResult = true; *hasResultType = true; break;
case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
+ case OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break;
+ case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break;
+ case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break;
+ case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break;
+ case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break;
case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
@@ -2374,6 +2542,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@@ -2385,6 +2557,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
case OpReadClockKHR: *hasResult = true; *hasResultType = true; break;
+ case OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break;
+ case OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
+ case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break;
case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break;
@@ -2423,6 +2600,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break;
case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;
case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;
+ case OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break;
+ case OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break;
case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
@@ -2448,6 +2627,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;
case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;
case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;
+ case OpRawAccessChainNV: *hasResult = true; *hasResultType = true; break;
case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2687,6 +2867,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+ case OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break;
case OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break;
case OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break;
case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
@@ -2699,6 +2880,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
+ case OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break;
+ case OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
@@ -2745,6 +2928,14 @@ inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShad
inline FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); }
inline FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); }
inline FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); }
+inline CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); }
+inline CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); }
+inline CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); }
+inline CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); }
+inline RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); }
+inline RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); }
+inline RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); }
+inline RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); }
} // end namespace spv
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp11 b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp11
index 5b643aeea..d6b4fb7bc 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp11
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.hpp11
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -69,6 +69,11 @@ enum class SourceLanguage : unsigned {
HLSL = 5,
CPP_for_OpenCL = 6,
SYCL = 7,
+ HERO_C = 8,
+ NZSL = 9,
+ WGSL = 10,
+ Slang = 11,
+ Zig = 12,
Max = 0x7fffffff,
};
@@ -168,12 +173,19 @@ enum class ExecutionMode : unsigned {
RoundingModeRTZ = 4463,
EarlyAndLateFragmentTestsAMD = 5017,
StencilRefReplacingEXT = 5027,
+ CoalescingAMDX = 5069,
+ MaxNodeRecursionAMDX = 5071,
+ StaticNumWorkgroupsAMDX = 5072,
+ ShaderIndexAMDX = 5073,
+ MaxNumWorkgroupsAMDX = 5077,
StencilRefUnchangedFrontAMD = 5079,
StencilRefGreaterFrontAMD = 5080,
StencilRefLessFrontAMD = 5081,
StencilRefUnchangedBackAMD = 5082,
StencilRefGreaterBackAMD = 5083,
StencilRefLessBackAMD = 5084,
+ QuadDerivativesKHR = 5088,
+ RequireFullQuadsKHR = 5089,
OutputLinesEXT = 5269,
OutputLinesNV = 5269,
OutputPrimitivesEXT = 5270,
@@ -198,9 +210,14 @@ enum class ExecutionMode : unsigned {
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
SchedulerTargetFmaxMhzINTEL = 5903,
+ MaximallyReconvergesKHR = 6023,
+ FPFastMathDefault = 6028,
StreamingInterfaceINTEL = 6154,
RegisterMapInterfaceINTEL = 6160,
NamedBarrierCountINTEL = 6417,
+ MaximumRegistersINTEL = 6461,
+ MaximumRegistersIdINTEL = 6462,
+ NamedMaximumRegistersINTEL = 6463,
Max = 0x7fffffff,
};
@@ -219,6 +236,8 @@ enum class StorageClass : unsigned {
Image = 11,
StorageBuffer = 12,
TileImageEXT = 4172,
+ NodePayloadAMDX = 5068,
+ NodeOutputPayloadAMDX = 5076,
CallableDataKHR = 5328,
CallableDataNV = 5328,
IncomingCallableDataKHR = 5329,
@@ -356,6 +375,8 @@ enum class ImageChannelDataType : unsigned {
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
+ UnsignedIntRaw10EXT = 19,
+ UnsignedIntRaw12EXT = 20,
Max = 0x7fffffff,
};
@@ -413,8 +434,11 @@ enum class FPFastMathModeShift : unsigned {
NSZ = 2,
AllowRecip = 3,
Fast = 4,
+ AllowContract = 16,
AllowContractFastINTEL = 16,
+ AllowReassoc = 17,
AllowReassocINTEL = 17,
+ AllowTransform = 18,
Max = 0x7fffffff,
};
@@ -425,8 +449,11 @@ enum class FPFastMathModeMask : unsigned {
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
+ AllowContract = 0x00010000,
AllowContractFastINTEL = 0x00010000,
+ AllowReassoc = 0x00020000,
AllowReassocINTEL = 0x00020000,
+ AllowTransform = 0x00040000,
};
enum class FPRoundingMode : unsigned {
@@ -516,7 +543,12 @@ enum class Decoration : unsigned {
NoUnsignedWrap = 4470,
WeightTextureQCOM = 4487,
BlockMatchTextureQCOM = 4488,
+ BlockMatchSamplerQCOM = 4499,
ExplicitInterpAMD = 4999,
+ NodeSharesPayloadLimitsWithAMDX = 5019,
+ NodeMaxPayloadsAMDX = 5020,
+ TrackFinishWritingAMDX = 5078,
+ PayloadNodeNameAMDX = 5091,
OverrideCoverageNV = 5248,
PassthroughNV = 5250,
ViewportRelativeNV = 5252,
@@ -566,6 +598,9 @@ enum class Decoration : unsigned {
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ StridesizeINTEL = 5883,
+ WordsizeINTEL = 5884,
+ TrueDualPortINTEL = 5885,
BurstCoalesceINTEL = 5899,
CacheSizeINTEL = 5900,
DontStaticallyCoalesceINTEL = 5901,
@@ -584,6 +619,8 @@ enum class Decoration : unsigned {
SingleElementVectorINTEL = 6085,
VectorComputeCallableFunctionINTEL = 6087,
MediaBlockIOINTEL = 6140,
+ StallFreeINTEL = 6151,
+ FPMaxErrorDecorationINTEL = 6170,
LatencyControlLabelINTEL = 6172,
LatencyControlConstraintINTEL = 6173,
ConduitKernelArgumentINTEL = 6175,
@@ -595,6 +632,11 @@ enum class Decoration : unsigned {
MMHostInterfaceMaxBurstINTEL = 6181,
MMHostInterfaceWaitRequestINTEL = 6182,
StableKernelArgumentINTEL = 6183,
+ HostAccessINTEL = 6188,
+ InitModeINTEL = 6190,
+ ImplementInRegisterMapINTEL = 6191,
+ CacheControlLoadINTEL = 6442,
+ CacheControlStoreINTEL = 6443,
Max = 0x7fffffff,
};
@@ -670,6 +712,8 @@ enum class BuiltIn : unsigned {
BaryCoordSmoothSampleAMD = 4997,
BaryCoordPullModelAMD = 4998,
FragStencilRefEXT = 5014,
+ CoalescedInputCountAMDX = 5021,
+ ShaderIndexAMDX = 5073,
ViewportMaskNV = 5253,
SecondaryPositionNV = 5257,
SecondaryViewportMaskNV = 5258,
@@ -723,6 +767,8 @@ enum class BuiltIn : unsigned {
HitKindNV = 5333,
CurrentRayTimeNV = 5334,
HitTriangleVertexPositionsKHR = 5335,
+ HitMicroTriangleVertexPositionsNV = 5337,
+ HitMicroTriangleVertexBarycentricsNV = 5344,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -730,6 +776,8 @@ enum class BuiltIn : unsigned {
SMCountNV = 5375,
WarpIDNV = 5376,
SMIDNV = 5377,
+ HitKindFrontFacingMicroTriangleNV = 5405,
+ HitKindBackFacingMicroTriangleNV = 5406,
CullMaskKHR = 6021,
Max = 0x7fffffff,
};
@@ -1031,6 +1079,7 @@ enum class Capability : unsigned {
TextureSampleWeightedQCOM = 4484,
TextureBoxFilterQCOM = 4485,
TextureBlockMatchQCOM = 4486,
+ TextureBlockMatch2QCOM = 4498,
Float16ImageAMD = 5008,
ImageGatherBiasLodAMD = 5009,
FragmentMaskAMD = 5010,
@@ -1038,6 +1087,8 @@ enum class Capability : unsigned {
ImageReadWriteLodAMD = 5015,
Int64ImageEXT = 5016,
ShaderClockKHR = 5055,
+ ShaderEnqueueAMDX = 5067,
+ QuadControlKHR = 5087,
SampleMaskOverrideCoverageNV = 5249,
GeometryShaderPassthroughNV = 5251,
ShaderViewportIndexLayerEXT = 5254,
@@ -1097,10 +1148,14 @@ enum class Capability : unsigned {
FragmentShaderPixelInterlockEXT = 5378,
DemoteToHelperInvocation = 5379,
DemoteToHelperInvocationEXT = 5379,
+ DisplacementMicromapNV = 5380,
RayTracingOpacityMicromapEXT = 5381,
ShaderInvocationReorderNV = 5383,
BindlessTextureNV = 5390,
RayQueryPositionFetchKHR = 5391,
+ AtomicFloat16VectorNV = 5404,
+ RayTracingDisplacementMicromapNV = 5409,
+ RawAccessChainsNV = 5414,
SubgroupShuffleINTEL = 5568,
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
@@ -1152,20 +1207,29 @@ enum class Capability : unsigned {
DotProduct = 6019,
DotProductKHR = 6019,
RayCullMaskKHR = 6020,
+ CooperativeMatrixKHR = 6022,
BitInstructions = 6025,
GroupNonUniformRotateKHR = 6026,
+ FloatControls2 = 6029,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
- LongConstantCompositeINTEL = 6089,
+ LongCompositesINTEL = 6089,
OptNoneINTEL = 6094,
AtomicFloat16AddEXT = 6095,
DebugInfoModuleINTEL = 6114,
BFloat16ConversionINTEL = 6115,
SplitBarrierINTEL = 6141,
+ FPGAClusterAttributesV2INTEL = 6150,
FPGAKernelAttributesv2INTEL = 6161,
+ FPMaxErrorINTEL = 6169,
FPGALatencyControlINTEL = 6171,
FPGAArgumentInterfacesINTEL = 6174,
+ GlobalVariableHostAccessINTEL = 6187,
+ GlobalVariableFPGADecorationsINTEL = 6189,
GroupUniformArithmeticKHR = 6400,
+ MaskedGatherScatterINTEL = 6427,
+ CacheControlsINTEL = 6441,
+ RegisterLimitsINTEL = 6460,
Max = 0x7fffffff,
};
@@ -1272,6 +1336,85 @@ enum class PackedVectorFormat : unsigned {
Max = 0x7fffffff,
};
+enum class CooperativeMatrixOperandsShift : unsigned {
+ MatrixASignedComponentsKHR = 0,
+ MatrixBSignedComponentsKHR = 1,
+ MatrixCSignedComponentsKHR = 2,
+ MatrixResultSignedComponentsKHR = 3,
+ SaturatingAccumulationKHR = 4,
+ Max = 0x7fffffff,
+};
+
+enum class CooperativeMatrixOperandsMask : unsigned {
+ MaskNone = 0,
+ MatrixASignedComponentsKHR = 0x00000001,
+ MatrixBSignedComponentsKHR = 0x00000002,
+ MatrixCSignedComponentsKHR = 0x00000004,
+ MatrixResultSignedComponentsKHR = 0x00000008,
+ SaturatingAccumulationKHR = 0x00000010,
+};
+
+enum class CooperativeMatrixLayout : unsigned {
+ RowMajorKHR = 0,
+ ColumnMajorKHR = 1,
+ Max = 0x7fffffff,
+};
+
+enum class CooperativeMatrixUse : unsigned {
+ MatrixAKHR = 0,
+ MatrixBKHR = 1,
+ MatrixAccumulatorKHR = 2,
+ Max = 0x7fffffff,
+};
+
+enum class InitializationModeQualifier : unsigned {
+ InitOnDeviceReprogramINTEL = 0,
+ InitOnDeviceResetINTEL = 1,
+ Max = 0x7fffffff,
+};
+
+enum class HostAccessQualifier : unsigned {
+ NoneINTEL = 0,
+ ReadINTEL = 1,
+ WriteINTEL = 2,
+ ReadWriteINTEL = 3,
+ Max = 0x7fffffff,
+};
+
+enum class LoadCacheControl : unsigned {
+ UncachedINTEL = 0,
+ CachedINTEL = 1,
+ StreamingINTEL = 2,
+ InvalidateAfterReadINTEL = 3,
+ ConstCachedINTEL = 4,
+ Max = 0x7fffffff,
+};
+
+enum class StoreCacheControl : unsigned {
+ UncachedINTEL = 0,
+ WriteThroughINTEL = 1,
+ WriteBackINTEL = 2,
+ StreamingINTEL = 3,
+ Max = 0x7fffffff,
+};
+
+enum class NamedMaximumNumberOfRegisters : unsigned {
+ AutoINTEL = 0,
+ Max = 0x7fffffff,
+};
+
+enum class RawAccessChainOperandsShift : unsigned {
+ RobustnessPerComponentNV = 0,
+ RobustnessPerElementNV = 1,
+ Max = 0x7fffffff,
+};
+
+enum class RawAccessChainOperandsMask : unsigned {
+ MaskNone = 0,
+ RobustnessPerComponentNV = 0x00000001,
+ RobustnessPerElementNV = 0x00000002,
+};
+
enum class Op : unsigned {
OpNop = 0,
OpUndef = 1,
@@ -1645,6 +1788,11 @@ enum class Op : unsigned {
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1656,6 +1804,10 @@ enum class Op : unsigned {
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1667,6 +1819,11 @@ enum class Op : unsigned {
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1705,6 +1862,8 @@ enum class Op : unsigned {
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1733,6 +1892,7 @@ enum class Op : unsigned {
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1974,6 +2134,7 @@ enum class Op : unsigned {
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1986,6 +2147,8 @@ enum class Op : unsigned {
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
Max = 0x7fffffff,
};
@@ -2363,6 +2526,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpSDotAccSat: *hasResult = true; *hasResultType = true; break;
case Op::OpUDotAccSat: *hasResult = true; *hasResultType = true; break;
case Op::OpSUDotAccSat: *hasResult = true; *hasResultType = true; break;
+ case Op::OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break;
+ case Op::OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break;
+ case Op::OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break;
+ case Op::OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break;
+ case Op::OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break;
case Op::OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case Op::OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case Op::OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;
@@ -2374,6 +2542,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break;
case Op::OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break;
case Op::OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case Op::OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case Op::OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break;
+ case Op::OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break;
+ case Op::OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break;
case Op::OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case Op::OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break;
case Op::OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break;
@@ -2385,6 +2557,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break;
case Op::OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break;
case Op::OpReadClockKHR: *hasResult = true; *hasResultType = true; break;
+ case Op::OpFinalizeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case Op::OpFinishWritingNodePayloadAMDX: *hasResult = true; *hasResultType = true; break;
+ case Op::OpInitializeNodePayloadsAMDX: *hasResult = false; *hasResultType = false; break;
+ case Op::OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break;
+ case Op::OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break;
case Op::OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break;
case Op::OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break;
case Op::OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break;
@@ -2423,6 +2600,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break;
case Op::OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break;
case Op::OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break;
+ case Op::OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break;
+ case Op::OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break;
case Op::OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break;
case Op::OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case Op::OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
@@ -2448,6 +2627,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break;
case Op::OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break;
case Op::OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break;
+ case Op::OpRawAccessChainNV: *hasResult = true; *hasResultType = true; break;
case Op::OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break;
case Op::OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break;
case Op::OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break;
@@ -2687,6 +2867,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case Op::OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
case Op::OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break;
+ case Op::OpCompositeConstructContinuedINTEL: *hasResult = true; *hasResultType = true; break;
case Op::OpConvertFToBF16INTEL: *hasResult = true; *hasResultType = true; break;
case Op::OpConvertBF16ToFINTEL: *hasResult = true; *hasResultType = true; break;
case Op::OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break;
@@ -2699,52 +2880,62 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break;
case Op::OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break;
case Op::OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break;
+ case Op::OpMaskedGatherINTEL: *hasResult = true; *hasResultType = true; break;
+ case Op::OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break;
}
}
#endif /* SPV_ENABLE_UTILITY_CODE */
// Overload bitwise operators for mask bit combining
-inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); }
-inline ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); }
-inline ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); }
-inline ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); }
-inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); }
-inline FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); }
-inline FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); }
-inline FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); }
-inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); }
-inline SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); }
-inline SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); }
-inline SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); }
-inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); }
-inline LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); }
-inline LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); }
-inline LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); }
-inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); }
-inline FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); }
-inline FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); }
-inline FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); }
-inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
-inline MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); }
-inline MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); }
-inline MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); }
-inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
-inline MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); }
-inline MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); }
-inline MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); }
-inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
-inline KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); }
-inline KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); }
-inline KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); }
-inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
-inline RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); }
-inline RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); }
-inline RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); }
-inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); }
-inline FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); }
-inline FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); }
-inline FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); }
+constexpr ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); }
+constexpr ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); }
+constexpr ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); }
+constexpr ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); }
+constexpr FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); }
+constexpr FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); }
+constexpr FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); }
+constexpr FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); }
+constexpr SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); }
+constexpr SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); }
+constexpr SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); }
+constexpr SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); }
+constexpr LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); }
+constexpr LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); }
+constexpr LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); }
+constexpr LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); }
+constexpr FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); }
+constexpr FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); }
+constexpr FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); }
+constexpr FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); }
+constexpr MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }
+constexpr MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); }
+constexpr MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); }
+constexpr MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); }
+constexpr MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); }
+constexpr MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); }
+constexpr MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); }
+constexpr MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); }
+constexpr KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); }
+constexpr KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); }
+constexpr KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); }
+constexpr KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); }
+constexpr RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); }
+constexpr RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); }
+constexpr RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); }
+constexpr RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); }
+constexpr FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); }
+constexpr FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); }
+constexpr FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); }
+constexpr FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); }
+constexpr CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); }
+constexpr CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); }
+constexpr CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); }
+constexpr CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); }
+constexpr RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); }
+constexpr RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); }
+constexpr RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); }
+constexpr RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); }
} // end namespace spv
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.json b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.json
index 908fe0573..204a9c569 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.json
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.json
@@ -6,7 +6,7 @@
"Comment":
[
[
- "Copyright (c) 2014-2020 The Khronos Group Inc.",
+ "Copyright (c) 2014-2024 The Khronos Group Inc.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and/or associated documentation files (the \"Materials\"),",
@@ -75,7 +75,12 @@
"OpenCL_CPP": 4,
"HLSL": 5,
"CPP_for_OpenCL": 6,
- "SYCL": 7
+ "SYCL": 7,
+ "HERO_C": 8,
+ "NZSL": 9,
+ "WGSL": 10,
+ "Slang": 11,
+ "Zig": 12
}
},
{
@@ -187,12 +192,19 @@
"RoundingModeRTZ": 4463,
"EarlyAndLateFragmentTestsAMD": 5017,
"StencilRefReplacingEXT": 5027,
+ "CoalescingAMDX": 5069,
+ "MaxNodeRecursionAMDX": 5071,
+ "StaticNumWorkgroupsAMDX": 5072,
+ "ShaderIndexAMDX": 5073,
+ "MaxNumWorkgroupsAMDX": 5077,
"StencilRefUnchangedFrontAMD": 5079,
"StencilRefGreaterFrontAMD": 5080,
"StencilRefLessFrontAMD": 5081,
"StencilRefUnchangedBackAMD": 5082,
"StencilRefGreaterBackAMD": 5083,
"StencilRefLessBackAMD": 5084,
+ "QuadDerivativesKHR": 5088,
+ "RequireFullQuadsKHR": 5089,
"OutputLinesEXT": 5269,
"OutputLinesNV": 5269,
"OutputPrimitivesEXT": 5270,
@@ -217,9 +229,14 @@
"NoGlobalOffsetINTEL": 5895,
"NumSIMDWorkitemsINTEL": 5896,
"SchedulerTargetFmaxMhzINTEL": 5903,
+ "MaximallyReconvergesKHR": 6023,
+ "FPFastMathDefault": 6028,
"StreamingInterfaceINTEL": 6154,
"RegisterMapInterfaceINTEL": 6160,
- "NamedBarrierCountINTEL": 6417
+ "NamedBarrierCountINTEL": 6417,
+ "MaximumRegistersINTEL": 6461,
+ "MaximumRegistersIdINTEL": 6462,
+ "NamedMaximumRegistersINTEL": 6463
}
},
{
@@ -241,6 +258,8 @@
"Image": 11,
"StorageBuffer": 12,
"TileImageEXT": 4172,
+ "NodePayloadAMDX": 5068,
+ "NodeOutputPayloadAMDX": 5076,
"CallableDataKHR": 5328,
"CallableDataNV": 5328,
"IncomingCallableDataKHR": 5329,
@@ -395,7 +414,9 @@
"HalfFloat": 13,
"Float": 14,
"UnormInt24": 15,
- "UnormInt101010_2": 16
+ "UnormInt101010_2": 16,
+ "UnsignedIntRaw10EXT": 19,
+ "UnsignedIntRaw12EXT": 20
}
},
{
@@ -435,8 +456,11 @@
"NSZ": 2,
"AllowRecip": 3,
"Fast": 4,
+ "AllowContract": 16,
"AllowContractFastINTEL": 16,
- "AllowReassocINTEL": 17
+ "AllowReassoc": 17,
+ "AllowReassocINTEL": 17,
+ "AllowTransform": 18
}
},
{
@@ -542,7 +566,12 @@
"NoUnsignedWrap": 4470,
"WeightTextureQCOM": 4487,
"BlockMatchTextureQCOM": 4488,
+ "BlockMatchSamplerQCOM": 4499,
"ExplicitInterpAMD": 4999,
+ "NodeSharesPayloadLimitsWithAMDX": 5019,
+ "NodeMaxPayloadsAMDX": 5020,
+ "TrackFinishWritingAMDX": 5078,
+ "PayloadNodeNameAMDX": 5091,
"OverrideCoverageNV": 5248,
"PassthroughNV": 5250,
"ViewportRelativeNV": 5252,
@@ -592,6 +621,9 @@
"MergeINTEL": 5834,
"BankBitsINTEL": 5835,
"ForcePow2DepthINTEL": 5836,
+ "StridesizeINTEL": 5883,
+ "WordsizeINTEL": 5884,
+ "TrueDualPortINTEL": 5885,
"BurstCoalesceINTEL": 5899,
"CacheSizeINTEL": 5900,
"DontStaticallyCoalesceINTEL": 5901,
@@ -610,6 +642,8 @@
"SingleElementVectorINTEL": 6085,
"VectorComputeCallableFunctionINTEL": 6087,
"MediaBlockIOINTEL": 6140,
+ "StallFreeINTEL": 6151,
+ "FPMaxErrorDecorationINTEL": 6170,
"LatencyControlLabelINTEL": 6172,
"LatencyControlConstraintINTEL": 6173,
"ConduitKernelArgumentINTEL": 6175,
@@ -620,7 +654,12 @@
"MMHostInterfaceReadWriteModeINTEL": 6180,
"MMHostInterfaceMaxBurstINTEL": 6181,
"MMHostInterfaceWaitRequestINTEL": 6182,
- "StableKernelArgumentINTEL": 6183
+ "StableKernelArgumentINTEL": 6183,
+ "HostAccessINTEL": 6188,
+ "InitModeINTEL": 6190,
+ "ImplementInRegisterMapINTEL": 6191,
+ "CacheControlLoadINTEL": 6442,
+ "CacheControlStoreINTEL": 6443
}
},
{
@@ -699,6 +738,8 @@
"BaryCoordSmoothSampleAMD": 4997,
"BaryCoordPullModelAMD": 4998,
"FragStencilRefEXT": 5014,
+ "CoalescedInputCountAMDX": 5021,
+ "ShaderIndexAMDX": 5073,
"ViewportMaskNV": 5253,
"SecondaryPositionNV": 5257,
"SecondaryViewportMaskNV": 5258,
@@ -752,6 +793,8 @@
"HitKindNV": 5333,
"CurrentRayTimeNV": 5334,
"HitTriangleVertexPositionsKHR": 5335,
+ "HitMicroTriangleVertexPositionsNV": 5337,
+ "HitMicroTriangleVertexBarycentricsNV": 5344,
"IncomingRayFlagsKHR": 5351,
"IncomingRayFlagsNV": 5351,
"RayGeometryIndexKHR": 5352,
@@ -759,6 +802,8 @@
"SMCountNV": 5375,
"WarpIDNV": 5376,
"SMIDNV": 5377,
+ "HitKindFrontFacingMicroTriangleNV": 5405,
+ "HitKindBackFacingMicroTriangleNV": 5406,
"CullMaskKHR": 6021
}
},
@@ -1011,6 +1056,7 @@
"TextureSampleWeightedQCOM": 4484,
"TextureBoxFilterQCOM": 4485,
"TextureBlockMatchQCOM": 4486,
+ "TextureBlockMatch2QCOM": 4498,
"Float16ImageAMD": 5008,
"ImageGatherBiasLodAMD": 5009,
"FragmentMaskAMD": 5010,
@@ -1018,6 +1064,8 @@
"ImageReadWriteLodAMD": 5015,
"Int64ImageEXT": 5016,
"ShaderClockKHR": 5055,
+ "ShaderEnqueueAMDX": 5067,
+ "QuadControlKHR": 5087,
"SampleMaskOverrideCoverageNV": 5249,
"GeometryShaderPassthroughNV": 5251,
"ShaderViewportIndexLayerEXT": 5254,
@@ -1077,10 +1125,14 @@
"FragmentShaderPixelInterlockEXT": 5378,
"DemoteToHelperInvocation": 5379,
"DemoteToHelperInvocationEXT": 5379,
+ "DisplacementMicromapNV": 5380,
"RayTracingOpacityMicromapEXT": 5381,
"ShaderInvocationReorderNV": 5383,
"BindlessTextureNV": 5390,
"RayQueryPositionFetchKHR": 5391,
+ "AtomicFloat16VectorNV": 5404,
+ "RayTracingDisplacementMicromapNV": 5409,
+ "RawAccessChainsNV": 5414,
"SubgroupShuffleINTEL": 5568,
"SubgroupBufferBlockIOINTEL": 5569,
"SubgroupImageBlockIOINTEL": 5570,
@@ -1132,20 +1184,29 @@
"DotProduct": 6019,
"DotProductKHR": 6019,
"RayCullMaskKHR": 6020,
+ "CooperativeMatrixKHR": 6022,
"BitInstructions": 6025,
"GroupNonUniformRotateKHR": 6026,
+ "FloatControls2": 6029,
"AtomicFloat32AddEXT": 6033,
"AtomicFloat64AddEXT": 6034,
- "LongConstantCompositeINTEL": 6089,
+ "LongCompositesINTEL": 6089,
"OptNoneINTEL": 6094,
"AtomicFloat16AddEXT": 6095,
"DebugInfoModuleINTEL": 6114,
"BFloat16ConversionINTEL": 6115,
"SplitBarrierINTEL": 6141,
+ "FPGAClusterAttributesV2INTEL": 6150,
"FPGAKernelAttributesv2INTEL": 6161,
+ "FPMaxErrorINTEL": 6169,
"FPGALatencyControlINTEL": 6171,
"FPGAArgumentInterfacesINTEL": 6174,
- "GroupUniformArithmeticKHR": 6400
+ "GlobalVariableHostAccessINTEL": 6187,
+ "GlobalVariableFPGADecorationsINTEL": 6189,
+ "GroupUniformArithmeticKHR": 6400,
+ "MaskedGatherScatterINTEL": 6427,
+ "CacheControlsINTEL": 6441,
+ "RegisterLimitsINTEL": 6460
}
},
{
@@ -1259,6 +1320,97 @@
}
},
{
+ "Name": "CooperativeMatrixOperands",
+ "Type": "Bit",
+ "Values":
+ {
+ "MatrixASignedComponentsKHR": 0,
+ "MatrixBSignedComponentsKHR": 1,
+ "MatrixCSignedComponentsKHR": 2,
+ "MatrixResultSignedComponentsKHR": 3,
+ "SaturatingAccumulationKHR": 4
+ }
+ },
+ {
+ "Name": "CooperativeMatrixLayout",
+ "Type": "Value",
+ "Values":
+ {
+ "RowMajorKHR": 0,
+ "ColumnMajorKHR": 1
+ }
+ },
+ {
+ "Name": "CooperativeMatrixUse",
+ "Type": "Value",
+ "Values":
+ {
+ "MatrixAKHR": 0,
+ "MatrixBKHR": 1,
+ "MatrixAccumulatorKHR": 2
+ }
+ },
+ {
+ "Name": "InitializationModeQualifier",
+ "Type": "Value",
+ "Values":
+ {
+ "InitOnDeviceReprogramINTEL": 0,
+ "InitOnDeviceResetINTEL": 1
+ }
+ },
+ {
+ "Name": "HostAccessQualifier",
+ "Type": "Value",
+ "Values":
+ {
+ "NoneINTEL": 0,
+ "ReadINTEL": 1,
+ "WriteINTEL": 2,
+ "ReadWriteINTEL": 3
+ }
+ },
+ {
+ "Name": "LoadCacheControl",
+ "Type": "Value",
+ "Values":
+ {
+ "UncachedINTEL": 0,
+ "CachedINTEL": 1,
+ "StreamingINTEL": 2,
+ "InvalidateAfterReadINTEL": 3,
+ "ConstCachedINTEL": 4
+ }
+ },
+ {
+ "Name": "StoreCacheControl",
+ "Type": "Value",
+ "Values":
+ {
+ "UncachedINTEL": 0,
+ "WriteThroughINTEL": 1,
+ "WriteBackINTEL": 2,
+ "StreamingINTEL": 3
+ }
+ },
+ {
+ "Name": "NamedMaximumNumberOfRegisters",
+ "Type": "Value",
+ "Values":
+ {
+ "AutoINTEL": 0
+ }
+ },
+ {
+ "Name": "RawAccessChainOperands",
+ "Type": "Bit",
+ "Values":
+ {
+ "RobustnessPerComponentNV": 0,
+ "RobustnessPerElementNV": 1
+ }
+ },
+ {
"Name": "Op",
"Type": "Value",
"Values":
@@ -1635,6 +1787,11 @@
"OpUDotAccSatKHR": 4454,
"OpSUDotAccSat": 4455,
"OpSUDotAccSatKHR": 4455,
+ "OpTypeCooperativeMatrixKHR": 4456,
+ "OpCooperativeMatrixLoadKHR": 4457,
+ "OpCooperativeMatrixStoreKHR": 4458,
+ "OpCooperativeMatrixMulAddKHR": 4459,
+ "OpCooperativeMatrixLengthKHR": 4460,
"OpTypeRayQueryKHR": 4472,
"OpRayQueryInitializeKHR": 4473,
"OpRayQueryTerminateKHR": 4474,
@@ -1646,6 +1803,10 @@
"OpImageBoxFilterQCOM": 4481,
"OpImageBlockMatchSSDQCOM": 4482,
"OpImageBlockMatchSADQCOM": 4483,
+ "OpImageBlockMatchWindowSSDQCOM": 4500,
+ "OpImageBlockMatchWindowSADQCOM": 4501,
+ "OpImageBlockMatchGatherSSDQCOM": 4502,
+ "OpImageBlockMatchGatherSADQCOM": 4503,
"OpGroupIAddNonUniformAMD": 5000,
"OpGroupFAddNonUniformAMD": 5001,
"OpGroupFMinNonUniformAMD": 5002,
@@ -1657,6 +1818,11 @@
"OpFragmentMaskFetchAMD": 5011,
"OpFragmentFetchAMD": 5012,
"OpReadClockKHR": 5056,
+ "OpFinalizeNodePayloadsAMDX": 5075,
+ "OpFinishWritingNodePayloadAMDX": 5078,
+ "OpInitializeNodePayloadsAMDX": 5090,
+ "OpGroupNonUniformQuadAllKHR": 5110,
+ "OpGroupNonUniformQuadAnyKHR": 5111,
"OpHitObjectRecordHitMotionNV": 5249,
"OpHitObjectRecordHitWithIndexMotionNV": 5250,
"OpHitObjectRecordMissMotionNV": 5251,
@@ -1695,6 +1861,8 @@
"OpSetMeshOutputsEXT": 5295,
"OpGroupNonUniformPartitionNV": 5296,
"OpWritePackedPrimitiveIndices4x8NV": 5299,
+ "OpFetchMicroTriangleVertexPositionNV": 5300,
+ "OpFetchMicroTriangleVertexBarycentricNV": 5301,
"OpReportIntersectionKHR": 5334,
"OpReportIntersectionNV": 5334,
"OpIgnoreIntersectionNV": 5335,
@@ -1723,6 +1891,7 @@
"OpConvertUToSampledImageNV": 5395,
"OpConvertSampledImageToUNV": 5396,
"OpSamplerImageAddressingModeNV": 5397,
+ "OpRawAccessChainNV": 5398,
"OpSubgroupShuffleINTEL": 5571,
"OpSubgroupShuffleDownINTEL": 5572,
"OpSubgroupShuffleUpINTEL": 5573,
@@ -1964,6 +2133,7 @@
"OpTypeStructContinuedINTEL": 6090,
"OpConstantCompositeContinuedINTEL": 6091,
"OpSpecConstantCompositeContinuedINTEL": 6092,
+ "OpCompositeConstructContinuedINTEL": 6096,
"OpConvertFToBF16INTEL": 6116,
"OpConvertBF16ToFINTEL": 6117,
"OpControlBarrierArriveINTEL": 6142,
@@ -1975,7 +2145,9 @@
"OpGroupBitwiseXorKHR": 6405,
"OpGroupLogicalAndKHR": 6406,
"OpGroupLogicalOrKHR": 6407,
- "OpGroupLogicalXorKHR": 6408
+ "OpGroupLogicalXorKHR": 6408,
+ "OpMaskedGatherINTEL": 6428,
+ "OpMaskedScatterINTEL": 6429
}
}
]
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.lua b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.lua
index 7e64fa624..6dcd1b8eb 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.lua
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.lua
@@ -1,4 +1,4 @@
--- Copyright (c) 2014-2020 The Khronos Group Inc.
+-- Copyright (c) 2014-2024 The Khronos Group Inc.
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and/or associated documentation files (the "Materials"),
@@ -60,6 +60,11 @@ spv = {
HLSL = 5,
CPP_for_OpenCL = 6,
SYCL = 7,
+ HERO_C = 8,
+ NZSL = 9,
+ WGSL = 10,
+ Slang = 11,
+ Zig = 12,
},
ExecutionModel = {
@@ -155,12 +160,19 @@ spv = {
RoundingModeRTZ = 4463,
EarlyAndLateFragmentTestsAMD = 5017,
StencilRefReplacingEXT = 5027,
+ CoalescingAMDX = 5069,
+ MaxNodeRecursionAMDX = 5071,
+ StaticNumWorkgroupsAMDX = 5072,
+ ShaderIndexAMDX = 5073,
+ MaxNumWorkgroupsAMDX = 5077,
StencilRefUnchangedFrontAMD = 5079,
StencilRefGreaterFrontAMD = 5080,
StencilRefLessFrontAMD = 5081,
StencilRefUnchangedBackAMD = 5082,
StencilRefGreaterBackAMD = 5083,
StencilRefLessBackAMD = 5084,
+ QuadDerivativesKHR = 5088,
+ RequireFullQuadsKHR = 5089,
OutputLinesEXT = 5269,
OutputLinesNV = 5269,
OutputPrimitivesEXT = 5270,
@@ -185,9 +197,14 @@ spv = {
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
SchedulerTargetFmaxMhzINTEL = 5903,
+ MaximallyReconvergesKHR = 6023,
+ FPFastMathDefault = 6028,
StreamingInterfaceINTEL = 6154,
RegisterMapInterfaceINTEL = 6160,
NamedBarrierCountINTEL = 6417,
+ MaximumRegistersINTEL = 6461,
+ MaximumRegistersIdINTEL = 6462,
+ NamedMaximumRegistersINTEL = 6463,
},
StorageClass = {
@@ -205,6 +222,8 @@ spv = {
Image = 11,
StorageBuffer = 12,
TileImageEXT = 4172,
+ NodePayloadAMDX = 5068,
+ NodeOutputPayloadAMDX = 5076,
CallableDataKHR = 5328,
CallableDataNV = 5328,
IncomingCallableDataKHR = 5329,
@@ -336,6 +355,8 @@ spv = {
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
+ UnsignedIntRaw10EXT = 19,
+ UnsignedIntRaw12EXT = 20,
},
ImageOperandsShift = {
@@ -391,8 +412,11 @@ spv = {
NSZ = 2,
AllowRecip = 3,
Fast = 4,
+ AllowContract = 16,
AllowContractFastINTEL = 16,
+ AllowReassoc = 17,
AllowReassocINTEL = 17,
+ AllowTransform = 18,
},
FPFastMathModeMask = {
@@ -402,8 +426,11 @@ spv = {
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
+ AllowContract = 0x00010000,
AllowContractFastINTEL = 0x00010000,
+ AllowReassoc = 0x00020000,
AllowReassocINTEL = 0x00020000,
+ AllowTransform = 0x00040000,
},
FPRoundingMode = {
@@ -489,7 +516,12 @@ spv = {
NoUnsignedWrap = 4470,
WeightTextureQCOM = 4487,
BlockMatchTextureQCOM = 4488,
+ BlockMatchSamplerQCOM = 4499,
ExplicitInterpAMD = 4999,
+ NodeSharesPayloadLimitsWithAMDX = 5019,
+ NodeMaxPayloadsAMDX = 5020,
+ TrackFinishWritingAMDX = 5078,
+ PayloadNodeNameAMDX = 5091,
OverrideCoverageNV = 5248,
PassthroughNV = 5250,
ViewportRelativeNV = 5252,
@@ -539,6 +571,9 @@ spv = {
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ StridesizeINTEL = 5883,
+ WordsizeINTEL = 5884,
+ TrueDualPortINTEL = 5885,
BurstCoalesceINTEL = 5899,
CacheSizeINTEL = 5900,
DontStaticallyCoalesceINTEL = 5901,
@@ -557,6 +592,8 @@ spv = {
SingleElementVectorINTEL = 6085,
VectorComputeCallableFunctionINTEL = 6087,
MediaBlockIOINTEL = 6140,
+ StallFreeINTEL = 6151,
+ FPMaxErrorDecorationINTEL = 6170,
LatencyControlLabelINTEL = 6172,
LatencyControlConstraintINTEL = 6173,
ConduitKernelArgumentINTEL = 6175,
@@ -568,6 +605,11 @@ spv = {
MMHostInterfaceMaxBurstINTEL = 6181,
MMHostInterfaceWaitRequestINTEL = 6182,
StableKernelArgumentINTEL = 6183,
+ HostAccessINTEL = 6188,
+ InitModeINTEL = 6190,
+ ImplementInRegisterMapINTEL = 6191,
+ CacheControlLoadINTEL = 6442,
+ CacheControlStoreINTEL = 6443,
},
BuiltIn = {
@@ -642,6 +684,8 @@ spv = {
BaryCoordSmoothSampleAMD = 4997,
BaryCoordPullModelAMD = 4998,
FragStencilRefEXT = 5014,
+ CoalescedInputCountAMDX = 5021,
+ ShaderIndexAMDX = 5073,
ViewportMaskNV = 5253,
SecondaryPositionNV = 5257,
SecondaryViewportMaskNV = 5258,
@@ -695,6 +739,8 @@ spv = {
HitKindNV = 5333,
CurrentRayTimeNV = 5334,
HitTriangleVertexPositionsKHR = 5335,
+ HitMicroTriangleVertexPositionsNV = 5337,
+ HitMicroTriangleVertexBarycentricsNV = 5344,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -702,6 +748,8 @@ spv = {
SMCountNV = 5375,
WarpIDNV = 5376,
SMIDNV = 5377,
+ HitKindFrontFacingMicroTriangleNV = 5405,
+ HitKindBackFacingMicroTriangleNV = 5406,
CullMaskKHR = 6021,
},
@@ -993,6 +1041,7 @@ spv = {
TextureSampleWeightedQCOM = 4484,
TextureBoxFilterQCOM = 4485,
TextureBlockMatchQCOM = 4486,
+ TextureBlockMatch2QCOM = 4498,
Float16ImageAMD = 5008,
ImageGatherBiasLodAMD = 5009,
FragmentMaskAMD = 5010,
@@ -1000,6 +1049,8 @@ spv = {
ImageReadWriteLodAMD = 5015,
Int64ImageEXT = 5016,
ShaderClockKHR = 5055,
+ ShaderEnqueueAMDX = 5067,
+ QuadControlKHR = 5087,
SampleMaskOverrideCoverageNV = 5249,
GeometryShaderPassthroughNV = 5251,
ShaderViewportIndexLayerEXT = 5254,
@@ -1059,10 +1110,14 @@ spv = {
FragmentShaderPixelInterlockEXT = 5378,
DemoteToHelperInvocation = 5379,
DemoteToHelperInvocationEXT = 5379,
+ DisplacementMicromapNV = 5380,
RayTracingOpacityMicromapEXT = 5381,
ShaderInvocationReorderNV = 5383,
BindlessTextureNV = 5390,
RayQueryPositionFetchKHR = 5391,
+ AtomicFloat16VectorNV = 5404,
+ RayTracingDisplacementMicromapNV = 5409,
+ RawAccessChainsNV = 5414,
SubgroupShuffleINTEL = 5568,
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
@@ -1114,20 +1169,29 @@ spv = {
DotProduct = 6019,
DotProductKHR = 6019,
RayCullMaskKHR = 6020,
+ CooperativeMatrixKHR = 6022,
BitInstructions = 6025,
GroupNonUniformRotateKHR = 6026,
+ FloatControls2 = 6029,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
- LongConstantCompositeINTEL = 6089,
+ LongCompositesINTEL = 6089,
OptNoneINTEL = 6094,
AtomicFloat16AddEXT = 6095,
DebugInfoModuleINTEL = 6114,
BFloat16ConversionINTEL = 6115,
SplitBarrierINTEL = 6141,
+ FPGAClusterAttributesV2INTEL = 6150,
FPGAKernelAttributesv2INTEL = 6161,
+ FPMaxErrorINTEL = 6169,
FPGALatencyControlINTEL = 6171,
FPGAArgumentInterfacesINTEL = 6174,
+ GlobalVariableHostAccessINTEL = 6187,
+ GlobalVariableFPGADecorationsINTEL = 6189,
GroupUniformArithmeticKHR = 6400,
+ MaskedGatherScatterINTEL = 6427,
+ CacheControlsINTEL = 6441,
+ RegisterLimitsINTEL = 6460,
},
RayFlagsShift = {
@@ -1223,6 +1287,76 @@ spv = {
PackedVectorFormat4x8BitKHR = 0,
},
+ CooperativeMatrixOperandsShift = {
+ MatrixASignedComponentsKHR = 0,
+ MatrixBSignedComponentsKHR = 1,
+ MatrixCSignedComponentsKHR = 2,
+ MatrixResultSignedComponentsKHR = 3,
+ SaturatingAccumulationKHR = 4,
+ },
+
+ CooperativeMatrixOperandsMask = {
+ MaskNone = 0,
+ MatrixASignedComponentsKHR = 0x00000001,
+ MatrixBSignedComponentsKHR = 0x00000002,
+ MatrixCSignedComponentsKHR = 0x00000004,
+ MatrixResultSignedComponentsKHR = 0x00000008,
+ SaturatingAccumulationKHR = 0x00000010,
+ },
+
+ CooperativeMatrixLayout = {
+ RowMajorKHR = 0,
+ ColumnMajorKHR = 1,
+ },
+
+ CooperativeMatrixUse = {
+ MatrixAKHR = 0,
+ MatrixBKHR = 1,
+ MatrixAccumulatorKHR = 2,
+ },
+
+ InitializationModeQualifier = {
+ InitOnDeviceReprogramINTEL = 0,
+ InitOnDeviceResetINTEL = 1,
+ },
+
+ HostAccessQualifier = {
+ NoneINTEL = 0,
+ ReadINTEL = 1,
+ WriteINTEL = 2,
+ ReadWriteINTEL = 3,
+ },
+
+ LoadCacheControl = {
+ UncachedINTEL = 0,
+ CachedINTEL = 1,
+ StreamingINTEL = 2,
+ InvalidateAfterReadINTEL = 3,
+ ConstCachedINTEL = 4,
+ },
+
+ StoreCacheControl = {
+ UncachedINTEL = 0,
+ WriteThroughINTEL = 1,
+ WriteBackINTEL = 2,
+ StreamingINTEL = 3,
+ },
+
+ NamedMaximumNumberOfRegisters = {
+ AutoINTEL = 0,
+ },
+
+ RawAccessChainOperandsShift = {
+ RobustnessPerComponentNV = 0,
+ RobustnessPerElementNV = 1,
+ },
+
+ RawAccessChainOperandsMask = {
+ MaskNone = 0,
+ RobustnessPerComponentNV = 0x00000001,
+ RobustnessPerElementNV = 0x00000002,
+ },
+
Op = {
OpNop = 0,
OpUndef = 1,
@@ -1596,6 +1730,11 @@ spv = {
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1607,6 +1746,10 @@ spv = {
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1618,6 +1761,11 @@ spv = {
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1656,6 +1804,8 @@ spv = {
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1684,6 +1834,7 @@ spv = {
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1925,6 +2076,7 @@ spv = {
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1937,6 +2089,8 @@ spv = {
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
},
}
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.py b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.py
index 7a9e8eebe..4b011cfe1 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spirv.py
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spirv.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2020 The Khronos Group Inc.
+# Copyright (c) 2014-2024 The Khronos Group Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and/or associated documentation files (the "Materials"),
@@ -60,6 +60,11 @@ spv = {
'HLSL' : 5,
'CPP_for_OpenCL' : 6,
'SYCL' : 7,
+ 'HERO_C' : 8,
+ 'NZSL' : 9,
+ 'WGSL' : 10,
+ 'Slang' : 11,
+ 'Zig' : 12,
},
'ExecutionModel' : {
@@ -155,12 +160,19 @@ spv = {
'RoundingModeRTZ' : 4463,
'EarlyAndLateFragmentTestsAMD' : 5017,
'StencilRefReplacingEXT' : 5027,
+ 'CoalescingAMDX' : 5069,
+ 'MaxNodeRecursionAMDX' : 5071,
+ 'StaticNumWorkgroupsAMDX' : 5072,
+ 'ShaderIndexAMDX' : 5073,
+ 'MaxNumWorkgroupsAMDX' : 5077,
'StencilRefUnchangedFrontAMD' : 5079,
'StencilRefGreaterFrontAMD' : 5080,
'StencilRefLessFrontAMD' : 5081,
'StencilRefUnchangedBackAMD' : 5082,
'StencilRefGreaterBackAMD' : 5083,
'StencilRefLessBackAMD' : 5084,
+ 'QuadDerivativesKHR' : 5088,
+ 'RequireFullQuadsKHR' : 5089,
'OutputLinesEXT' : 5269,
'OutputLinesNV' : 5269,
'OutputPrimitivesEXT' : 5270,
@@ -185,9 +197,14 @@ spv = {
'NoGlobalOffsetINTEL' : 5895,
'NumSIMDWorkitemsINTEL' : 5896,
'SchedulerTargetFmaxMhzINTEL' : 5903,
+ 'MaximallyReconvergesKHR' : 6023,
+ 'FPFastMathDefault' : 6028,
'StreamingInterfaceINTEL' : 6154,
'RegisterMapInterfaceINTEL' : 6160,
'NamedBarrierCountINTEL' : 6417,
+ 'MaximumRegistersINTEL' : 6461,
+ 'MaximumRegistersIdINTEL' : 6462,
+ 'NamedMaximumRegistersINTEL' : 6463,
},
'StorageClass' : {
@@ -205,6 +222,8 @@ spv = {
'Image' : 11,
'StorageBuffer' : 12,
'TileImageEXT' : 4172,
+ 'NodePayloadAMDX' : 5068,
+ 'NodeOutputPayloadAMDX' : 5076,
'CallableDataKHR' : 5328,
'CallableDataNV' : 5328,
'IncomingCallableDataKHR' : 5329,
@@ -336,6 +355,8 @@ spv = {
'Float' : 14,
'UnormInt24' : 15,
'UnormInt101010_2' : 16,
+ 'UnsignedIntRaw10EXT' : 19,
+ 'UnsignedIntRaw12EXT' : 20,
},
'ImageOperandsShift' : {
@@ -391,8 +412,11 @@ spv = {
'NSZ' : 2,
'AllowRecip' : 3,
'Fast' : 4,
+ 'AllowContract' : 16,
'AllowContractFastINTEL' : 16,
+ 'AllowReassoc' : 17,
'AllowReassocINTEL' : 17,
+ 'AllowTransform' : 18,
},
'FPFastMathModeMask' : {
@@ -402,8 +426,11 @@ spv = {
'NSZ' : 0x00000004,
'AllowRecip' : 0x00000008,
'Fast' : 0x00000010,
+ 'AllowContract' : 0x00010000,
'AllowContractFastINTEL' : 0x00010000,
+ 'AllowReassoc' : 0x00020000,
'AllowReassocINTEL' : 0x00020000,
+ 'AllowTransform' : 0x00040000,
},
'FPRoundingMode' : {
@@ -489,7 +516,12 @@ spv = {
'NoUnsignedWrap' : 4470,
'WeightTextureQCOM' : 4487,
'BlockMatchTextureQCOM' : 4488,
+ 'BlockMatchSamplerQCOM' : 4499,
'ExplicitInterpAMD' : 4999,
+ 'NodeSharesPayloadLimitsWithAMDX' : 5019,
+ 'NodeMaxPayloadsAMDX' : 5020,
+ 'TrackFinishWritingAMDX' : 5078,
+ 'PayloadNodeNameAMDX' : 5091,
'OverrideCoverageNV' : 5248,
'PassthroughNV' : 5250,
'ViewportRelativeNV' : 5252,
@@ -539,6 +571,9 @@ spv = {
'MergeINTEL' : 5834,
'BankBitsINTEL' : 5835,
'ForcePow2DepthINTEL' : 5836,
+ 'StridesizeINTEL' : 5883,
+ 'WordsizeINTEL' : 5884,
+ 'TrueDualPortINTEL' : 5885,
'BurstCoalesceINTEL' : 5899,
'CacheSizeINTEL' : 5900,
'DontStaticallyCoalesceINTEL' : 5901,
@@ -557,6 +592,8 @@ spv = {
'SingleElementVectorINTEL' : 6085,
'VectorComputeCallableFunctionINTEL' : 6087,
'MediaBlockIOINTEL' : 6140,
+ 'StallFreeINTEL' : 6151,
+ 'FPMaxErrorDecorationINTEL' : 6170,
'LatencyControlLabelINTEL' : 6172,
'LatencyControlConstraintINTEL' : 6173,
'ConduitKernelArgumentINTEL' : 6175,
@@ -568,6 +605,11 @@ spv = {
'MMHostInterfaceMaxBurstINTEL' : 6181,
'MMHostInterfaceWaitRequestINTEL' : 6182,
'StableKernelArgumentINTEL' : 6183,
+ 'HostAccessINTEL' : 6188,
+ 'InitModeINTEL' : 6190,
+ 'ImplementInRegisterMapINTEL' : 6191,
+ 'CacheControlLoadINTEL' : 6442,
+ 'CacheControlStoreINTEL' : 6443,
},
'BuiltIn' : {
@@ -642,6 +684,8 @@ spv = {
'BaryCoordSmoothSampleAMD' : 4997,
'BaryCoordPullModelAMD' : 4998,
'FragStencilRefEXT' : 5014,
+ 'CoalescedInputCountAMDX' : 5021,
+ 'ShaderIndexAMDX' : 5073,
'ViewportMaskNV' : 5253,
'SecondaryPositionNV' : 5257,
'SecondaryViewportMaskNV' : 5258,
@@ -695,6 +739,8 @@ spv = {
'HitKindNV' : 5333,
'CurrentRayTimeNV' : 5334,
'HitTriangleVertexPositionsKHR' : 5335,
+ 'HitMicroTriangleVertexPositionsNV' : 5337,
+ 'HitMicroTriangleVertexBarycentricsNV' : 5344,
'IncomingRayFlagsKHR' : 5351,
'IncomingRayFlagsNV' : 5351,
'RayGeometryIndexKHR' : 5352,
@@ -702,6 +748,8 @@ spv = {
'SMCountNV' : 5375,
'WarpIDNV' : 5376,
'SMIDNV' : 5377,
+ 'HitKindFrontFacingMicroTriangleNV' : 5405,
+ 'HitKindBackFacingMicroTriangleNV' : 5406,
'CullMaskKHR' : 6021,
},
@@ -993,6 +1041,7 @@ spv = {
'TextureSampleWeightedQCOM' : 4484,
'TextureBoxFilterQCOM' : 4485,
'TextureBlockMatchQCOM' : 4486,
+ 'TextureBlockMatch2QCOM' : 4498,
'Float16ImageAMD' : 5008,
'ImageGatherBiasLodAMD' : 5009,
'FragmentMaskAMD' : 5010,
@@ -1000,6 +1049,8 @@ spv = {
'ImageReadWriteLodAMD' : 5015,
'Int64ImageEXT' : 5016,
'ShaderClockKHR' : 5055,
+ 'ShaderEnqueueAMDX' : 5067,
+ 'QuadControlKHR' : 5087,
'SampleMaskOverrideCoverageNV' : 5249,
'GeometryShaderPassthroughNV' : 5251,
'ShaderViewportIndexLayerEXT' : 5254,
@@ -1059,10 +1110,14 @@ spv = {
'FragmentShaderPixelInterlockEXT' : 5378,
'DemoteToHelperInvocation' : 5379,
'DemoteToHelperInvocationEXT' : 5379,
+ 'DisplacementMicromapNV' : 5380,
'RayTracingOpacityMicromapEXT' : 5381,
'ShaderInvocationReorderNV' : 5383,
'BindlessTextureNV' : 5390,
'RayQueryPositionFetchKHR' : 5391,
+ 'AtomicFloat16VectorNV' : 5404,
+ 'RayTracingDisplacementMicromapNV' : 5409,
+ 'RawAccessChainsNV' : 5414,
'SubgroupShuffleINTEL' : 5568,
'SubgroupBufferBlockIOINTEL' : 5569,
'SubgroupImageBlockIOINTEL' : 5570,
@@ -1114,20 +1169,29 @@ spv = {
'DotProduct' : 6019,
'DotProductKHR' : 6019,
'RayCullMaskKHR' : 6020,
+ 'CooperativeMatrixKHR' : 6022,
'BitInstructions' : 6025,
'GroupNonUniformRotateKHR' : 6026,
+ 'FloatControls2' : 6029,
'AtomicFloat32AddEXT' : 6033,
'AtomicFloat64AddEXT' : 6034,
- 'LongConstantCompositeINTEL' : 6089,
+ 'LongCompositesINTEL' : 6089,
'OptNoneINTEL' : 6094,
'AtomicFloat16AddEXT' : 6095,
'DebugInfoModuleINTEL' : 6114,
'BFloat16ConversionINTEL' : 6115,
'SplitBarrierINTEL' : 6141,
+ 'FPGAClusterAttributesV2INTEL' : 6150,
'FPGAKernelAttributesv2INTEL' : 6161,
+ 'FPMaxErrorINTEL' : 6169,
'FPGALatencyControlINTEL' : 6171,
'FPGAArgumentInterfacesINTEL' : 6174,
+ 'GlobalVariableHostAccessINTEL' : 6187,
+ 'GlobalVariableFPGADecorationsINTEL' : 6189,
'GroupUniformArithmeticKHR' : 6400,
+ 'MaskedGatherScatterINTEL' : 6427,
+ 'CacheControlsINTEL' : 6441,
+ 'RegisterLimitsINTEL' : 6460,
},
'RayFlagsShift' : {
@@ -1223,6 +1287,76 @@ spv = {
'PackedVectorFormat4x8BitKHR' : 0,
},
+ 'CooperativeMatrixOperandsShift' : {
+ 'MatrixASignedComponentsKHR' : 0,
+ 'MatrixBSignedComponentsKHR' : 1,
+ 'MatrixCSignedComponentsKHR' : 2,
+ 'MatrixResultSignedComponentsKHR' : 3,
+ 'SaturatingAccumulationKHR' : 4,
+ },
+
+ 'CooperativeMatrixOperandsMask' : {
+ 'MaskNone' : 0,
+ 'MatrixASignedComponentsKHR' : 0x00000001,
+ 'MatrixBSignedComponentsKHR' : 0x00000002,
+ 'MatrixCSignedComponentsKHR' : 0x00000004,
+ 'MatrixResultSignedComponentsKHR' : 0x00000008,
+ 'SaturatingAccumulationKHR' : 0x00000010,
+ },
+
+ 'CooperativeMatrixLayout' : {
+ 'RowMajorKHR' : 0,
+ 'ColumnMajorKHR' : 1,
+ },
+
+ 'CooperativeMatrixUse' : {
+ 'MatrixAKHR' : 0,
+ 'MatrixBKHR' : 1,
+ 'MatrixAccumulatorKHR' : 2,
+ },
+
+ 'InitializationModeQualifier' : {
+ 'InitOnDeviceReprogramINTEL' : 0,
+ 'InitOnDeviceResetINTEL' : 1,
+ },
+
+ 'HostAccessQualifier' : {
+ 'NoneINTEL' : 0,
+ 'ReadINTEL' : 1,
+ 'WriteINTEL' : 2,
+ 'ReadWriteINTEL' : 3,
+ },
+
+ 'LoadCacheControl' : {
+ 'UncachedINTEL' : 0,
+ 'CachedINTEL' : 1,
+ 'StreamingINTEL' : 2,
+ 'InvalidateAfterReadINTEL' : 3,
+ 'ConstCachedINTEL' : 4,
+ },
+
+ 'StoreCacheControl' : {
+ 'UncachedINTEL' : 0,
+ 'WriteThroughINTEL' : 1,
+ 'WriteBackINTEL' : 2,
+ 'StreamingINTEL' : 3,
+ },
+
+ 'NamedMaximumNumberOfRegisters' : {
+ 'AutoINTEL' : 0,
+ },
+
+ 'RawAccessChainOperandsShift' : {
+ 'RobustnessPerComponentNV' : 0,
+ 'RobustnessPerElementNV' : 1,
+ },
+
+ 'RawAccessChainOperandsMask' : {
+ 'MaskNone' : 0,
+ 'RobustnessPerComponentNV' : 0x00000001,
+ 'RobustnessPerElementNV' : 0x00000002,
+ },
+
'Op' : {
'OpNop' : 0,
'OpUndef' : 1,
@@ -1596,6 +1730,11 @@ spv = {
'OpUDotAccSatKHR' : 4454,
'OpSUDotAccSat' : 4455,
'OpSUDotAccSatKHR' : 4455,
+ 'OpTypeCooperativeMatrixKHR' : 4456,
+ 'OpCooperativeMatrixLoadKHR' : 4457,
+ 'OpCooperativeMatrixStoreKHR' : 4458,
+ 'OpCooperativeMatrixMulAddKHR' : 4459,
+ 'OpCooperativeMatrixLengthKHR' : 4460,
'OpTypeRayQueryKHR' : 4472,
'OpRayQueryInitializeKHR' : 4473,
'OpRayQueryTerminateKHR' : 4474,
@@ -1607,6 +1746,10 @@ spv = {
'OpImageBoxFilterQCOM' : 4481,
'OpImageBlockMatchSSDQCOM' : 4482,
'OpImageBlockMatchSADQCOM' : 4483,
+ 'OpImageBlockMatchWindowSSDQCOM' : 4500,
+ 'OpImageBlockMatchWindowSADQCOM' : 4501,
+ 'OpImageBlockMatchGatherSSDQCOM' : 4502,
+ 'OpImageBlockMatchGatherSADQCOM' : 4503,
'OpGroupIAddNonUniformAMD' : 5000,
'OpGroupFAddNonUniformAMD' : 5001,
'OpGroupFMinNonUniformAMD' : 5002,
@@ -1618,6 +1761,11 @@ spv = {
'OpFragmentMaskFetchAMD' : 5011,
'OpFragmentFetchAMD' : 5012,
'OpReadClockKHR' : 5056,
+ 'OpFinalizeNodePayloadsAMDX' : 5075,
+ 'OpFinishWritingNodePayloadAMDX' : 5078,
+ 'OpInitializeNodePayloadsAMDX' : 5090,
+ 'OpGroupNonUniformQuadAllKHR' : 5110,
+ 'OpGroupNonUniformQuadAnyKHR' : 5111,
'OpHitObjectRecordHitMotionNV' : 5249,
'OpHitObjectRecordHitWithIndexMotionNV' : 5250,
'OpHitObjectRecordMissMotionNV' : 5251,
@@ -1656,6 +1804,8 @@ spv = {
'OpSetMeshOutputsEXT' : 5295,
'OpGroupNonUniformPartitionNV' : 5296,
'OpWritePackedPrimitiveIndices4x8NV' : 5299,
+ 'OpFetchMicroTriangleVertexPositionNV' : 5300,
+ 'OpFetchMicroTriangleVertexBarycentricNV' : 5301,
'OpReportIntersectionKHR' : 5334,
'OpReportIntersectionNV' : 5334,
'OpIgnoreIntersectionNV' : 5335,
@@ -1684,6 +1834,7 @@ spv = {
'OpConvertUToSampledImageNV' : 5395,
'OpConvertSampledImageToUNV' : 5396,
'OpSamplerImageAddressingModeNV' : 5397,
+ 'OpRawAccessChainNV' : 5398,
'OpSubgroupShuffleINTEL' : 5571,
'OpSubgroupShuffleDownINTEL' : 5572,
'OpSubgroupShuffleUpINTEL' : 5573,
@@ -1925,6 +2076,7 @@ spv = {
'OpTypeStructContinuedINTEL' : 6090,
'OpConstantCompositeContinuedINTEL' : 6091,
'OpSpecConstantCompositeContinuedINTEL' : 6092,
+ 'OpCompositeConstructContinuedINTEL' : 6096,
'OpConvertFToBF16INTEL' : 6116,
'OpConvertBF16ToFINTEL' : 6117,
'OpControlBarrierArriveINTEL' : 6142,
@@ -1937,6 +2089,8 @@ spv = {
'OpGroupLogicalAndKHR' : 6406,
'OpGroupLogicalOrKHR' : 6407,
'OpGroupLogicalXorKHR' : 6408,
+ 'OpMaskedGatherINTEL' : 6428,
+ 'OpMaskedScatterINTEL' : 6429,
},
}
diff --git a/third_party/SPIRV-Headers/include/spirv/unified1/spv.d b/third_party/SPIRV-Headers/include/spirv/unified1/spv.d
index 8c85024f5..64c115e02 100644
--- a/third_party/SPIRV-Headers/include/spirv/unified1/spv.d
+++ b/third_party/SPIRV-Headers/include/spirv/unified1/spv.d
@@ -1,5 +1,5 @@
/+
- + Copyright (c) 2014-2020 The Khronos Group Inc.
+ + Copyright (c) 2014-2024 The Khronos Group Inc.
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and/or associated documentation files (the "Materials"),
@@ -68,6 +68,11 @@ enum SourceLanguage : uint
HLSL = 5,
CPP_for_OpenCL = 6,
SYCL = 7,
+ HERO_C = 8,
+ NZSL = 9,
+ WGSL = 10,
+ Slang = 11,
+ Zig = 12,
}
enum ExecutionModel : uint
@@ -167,12 +172,19 @@ enum ExecutionMode : uint
RoundingModeRTZ = 4463,
EarlyAndLateFragmentTestsAMD = 5017,
StencilRefReplacingEXT = 5027,
+ CoalescingAMDX = 5069,
+ MaxNodeRecursionAMDX = 5071,
+ StaticNumWorkgroupsAMDX = 5072,
+ ShaderIndexAMDX = 5073,
+ MaxNumWorkgroupsAMDX = 5077,
StencilRefUnchangedFrontAMD = 5079,
StencilRefGreaterFrontAMD = 5080,
StencilRefLessFrontAMD = 5081,
StencilRefUnchangedBackAMD = 5082,
StencilRefGreaterBackAMD = 5083,
StencilRefLessBackAMD = 5084,
+ QuadDerivativesKHR = 5088,
+ RequireFullQuadsKHR = 5089,
OutputLinesEXT = 5269,
OutputLinesNV = 5269,
OutputPrimitivesEXT = 5270,
@@ -197,9 +209,14 @@ enum ExecutionMode : uint
NoGlobalOffsetINTEL = 5895,
NumSIMDWorkitemsINTEL = 5896,
SchedulerTargetFmaxMhzINTEL = 5903,
+ MaximallyReconvergesKHR = 6023,
+ FPFastMathDefault = 6028,
StreamingInterfaceINTEL = 6154,
RegisterMapInterfaceINTEL = 6160,
NamedBarrierCountINTEL = 6417,
+ MaximumRegistersINTEL = 6461,
+ MaximumRegistersIdINTEL = 6462,
+ NamedMaximumRegistersINTEL = 6463,
}
enum StorageClass : uint
@@ -218,6 +235,8 @@ enum StorageClass : uint
Image = 11,
StorageBuffer = 12,
TileImageEXT = 4172,
+ NodePayloadAMDX = 5068,
+ NodeOutputPayloadAMDX = 5076,
CallableDataKHR = 5328,
CallableDataNV = 5328,
IncomingCallableDataKHR = 5329,
@@ -355,6 +374,8 @@ enum ImageChannelDataType : uint
Float = 14,
UnormInt24 = 15,
UnormInt101010_2 = 16,
+ UnsignedIntRaw10EXT = 19,
+ UnsignedIntRaw12EXT = 20,
}
enum ImageOperandsShift : uint
@@ -413,8 +434,11 @@ enum FPFastMathModeShift : uint
NSZ = 2,
AllowRecip = 3,
Fast = 4,
+ AllowContract = 16,
AllowContractFastINTEL = 16,
+ AllowReassoc = 17,
AllowReassocINTEL = 17,
+ AllowTransform = 18,
}
enum FPFastMathModeMask : uint
@@ -425,8 +449,11 @@ enum FPFastMathModeMask : uint
NSZ = 0x00000004,
AllowRecip = 0x00000008,
Fast = 0x00000010,
+ AllowContract = 0x00010000,
AllowContractFastINTEL = 0x00010000,
+ AllowReassoc = 0x00020000,
AllowReassocINTEL = 0x00020000,
+ AllowTransform = 0x00040000,
}
enum FPRoundingMode : uint
@@ -517,7 +544,12 @@ enum Decoration : uint
NoUnsignedWrap = 4470,
WeightTextureQCOM = 4487,
BlockMatchTextureQCOM = 4488,
+ BlockMatchSamplerQCOM = 4499,
ExplicitInterpAMD = 4999,
+ NodeSharesPayloadLimitsWithAMDX = 5019,
+ NodeMaxPayloadsAMDX = 5020,
+ TrackFinishWritingAMDX = 5078,
+ PayloadNodeNameAMDX = 5091,
OverrideCoverageNV = 5248,
PassthroughNV = 5250,
ViewportRelativeNV = 5252,
@@ -567,6 +599,9 @@ enum Decoration : uint
MergeINTEL = 5834,
BankBitsINTEL = 5835,
ForcePow2DepthINTEL = 5836,
+ StridesizeINTEL = 5883,
+ WordsizeINTEL = 5884,
+ TrueDualPortINTEL = 5885,
BurstCoalesceINTEL = 5899,
CacheSizeINTEL = 5900,
DontStaticallyCoalesceINTEL = 5901,
@@ -585,6 +620,8 @@ enum Decoration : uint
SingleElementVectorINTEL = 6085,
VectorComputeCallableFunctionINTEL = 6087,
MediaBlockIOINTEL = 6140,
+ StallFreeINTEL = 6151,
+ FPMaxErrorDecorationINTEL = 6170,
LatencyControlLabelINTEL = 6172,
LatencyControlConstraintINTEL = 6173,
ConduitKernelArgumentINTEL = 6175,
@@ -596,6 +633,11 @@ enum Decoration : uint
MMHostInterfaceMaxBurstINTEL = 6181,
MMHostInterfaceWaitRequestINTEL = 6182,
StableKernelArgumentINTEL = 6183,
+ HostAccessINTEL = 6188,
+ InitModeINTEL = 6190,
+ ImplementInRegisterMapINTEL = 6191,
+ CacheControlLoadINTEL = 6442,
+ CacheControlStoreINTEL = 6443,
}
enum BuiltIn : uint
@@ -671,6 +713,8 @@ enum BuiltIn : uint
BaryCoordSmoothSampleAMD = 4997,
BaryCoordPullModelAMD = 4998,
FragStencilRefEXT = 5014,
+ CoalescedInputCountAMDX = 5021,
+ ShaderIndexAMDX = 5073,
ViewportMaskNV = 5253,
SecondaryPositionNV = 5257,
SecondaryViewportMaskNV = 5258,
@@ -724,6 +768,8 @@ enum BuiltIn : uint
HitKindNV = 5333,
CurrentRayTimeNV = 5334,
HitTriangleVertexPositionsKHR = 5335,
+ HitMicroTriangleVertexPositionsNV = 5337,
+ HitMicroTriangleVertexBarycentricsNV = 5344,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -731,6 +777,8 @@ enum BuiltIn : uint
SMCountNV = 5375,
WarpIDNV = 5376,
SMIDNV = 5377,
+ HitKindFrontFacingMicroTriangleNV = 5405,
+ HitKindBackFacingMicroTriangleNV = 5406,
CullMaskKHR = 6021,
}
@@ -1038,6 +1086,7 @@ enum Capability : uint
TextureSampleWeightedQCOM = 4484,
TextureBoxFilterQCOM = 4485,
TextureBlockMatchQCOM = 4486,
+ TextureBlockMatch2QCOM = 4498,
Float16ImageAMD = 5008,
ImageGatherBiasLodAMD = 5009,
FragmentMaskAMD = 5010,
@@ -1045,6 +1094,8 @@ enum Capability : uint
ImageReadWriteLodAMD = 5015,
Int64ImageEXT = 5016,
ShaderClockKHR = 5055,
+ ShaderEnqueueAMDX = 5067,
+ QuadControlKHR = 5087,
SampleMaskOverrideCoverageNV = 5249,
GeometryShaderPassthroughNV = 5251,
ShaderViewportIndexLayerEXT = 5254,
@@ -1104,10 +1155,14 @@ enum Capability : uint
FragmentShaderPixelInterlockEXT = 5378,
DemoteToHelperInvocation = 5379,
DemoteToHelperInvocationEXT = 5379,
+ DisplacementMicromapNV = 5380,
RayTracingOpacityMicromapEXT = 5381,
ShaderInvocationReorderNV = 5383,
BindlessTextureNV = 5390,
RayQueryPositionFetchKHR = 5391,
+ AtomicFloat16VectorNV = 5404,
+ RayTracingDisplacementMicromapNV = 5409,
+ RawAccessChainsNV = 5414,
SubgroupShuffleINTEL = 5568,
SubgroupBufferBlockIOINTEL = 5569,
SubgroupImageBlockIOINTEL = 5570,
@@ -1159,20 +1214,29 @@ enum Capability : uint
DotProduct = 6019,
DotProductKHR = 6019,
RayCullMaskKHR = 6020,
+ CooperativeMatrixKHR = 6022,
BitInstructions = 6025,
GroupNonUniformRotateKHR = 6026,
+ FloatControls2 = 6029,
AtomicFloat32AddEXT = 6033,
AtomicFloat64AddEXT = 6034,
- LongConstantCompositeINTEL = 6089,
+ LongCompositesINTEL = 6089,
OptNoneINTEL = 6094,
AtomicFloat16AddEXT = 6095,
DebugInfoModuleINTEL = 6114,
BFloat16ConversionINTEL = 6115,
SplitBarrierINTEL = 6141,
+ FPGAClusterAttributesV2INTEL = 6150,
FPGAKernelAttributesv2INTEL = 6161,
+ FPMaxErrorINTEL = 6169,
FPGALatencyControlINTEL = 6171,
FPGAArgumentInterfacesINTEL = 6174,
+ GlobalVariableHostAccessINTEL = 6187,
+ GlobalVariableFPGADecorationsINTEL = 6189,
GroupUniformArithmeticKHR = 6400,
+ MaskedGatherScatterINTEL = 6427,
+ CacheControlsINTEL = 6441,
+ RegisterLimitsINTEL = 6460,
}
enum RayFlagsShift : uint
@@ -1280,6 +1344,87 @@ enum PackedVectorFormat : uint
PackedVectorFormat4x8BitKHR = 0,
}
+enum CooperativeMatrixOperandsShift : uint
+{
+ MatrixASignedComponentsKHR = 0,
+ MatrixBSignedComponentsKHR = 1,
+ MatrixCSignedComponentsKHR = 2,
+ MatrixResultSignedComponentsKHR = 3,
+ SaturatingAccumulationKHR = 4,
+}
+
+enum CooperativeMatrixOperandsMask : uint
+{
+ MaskNone = 0,
+ MatrixASignedComponentsKHR = 0x00000001,
+ MatrixBSignedComponentsKHR = 0x00000002,
+ MatrixCSignedComponentsKHR = 0x00000004,
+ MatrixResultSignedComponentsKHR = 0x00000008,
+ SaturatingAccumulationKHR = 0x00000010,
+}
+
+enum CooperativeMatrixLayout : uint
+{
+ RowMajorKHR = 0,
+ ColumnMajorKHR = 1,
+}
+
+enum CooperativeMatrixUse : uint
+{
+ MatrixAKHR = 0,
+ MatrixBKHR = 1,
+ MatrixAccumulatorKHR = 2,
+}
+
+enum InitializationModeQualifier : uint
+{
+ InitOnDeviceReprogramINTEL = 0,
+ InitOnDeviceResetINTEL = 1,
+}
+
+enum HostAccessQualifier : uint
+{
+ NoneINTEL = 0,
+ ReadINTEL = 1,
+ WriteINTEL = 2,
+ ReadWriteINTEL = 3,
+}
+
+enum LoadCacheControl : uint
+{
+ UncachedINTEL = 0,
+ CachedINTEL = 1,
+ StreamingINTEL = 2,
+ InvalidateAfterReadINTEL = 3,
+ ConstCachedINTEL = 4,
+}
+
+enum StoreCacheControl : uint
+{
+ UncachedINTEL = 0,
+ WriteThroughINTEL = 1,
+ WriteBackINTEL = 2,
+ StreamingINTEL = 3,
+}
+
+enum NamedMaximumNumberOfRegisters : uint
+{
+ AutoINTEL = 0,
+}
+
+enum RawAccessChainOperandsShift : uint
+{
+ RobustnessPerComponentNV = 0,
+ RobustnessPerElementNV = 1,
+}
+
+enum RawAccessChainOperandsMask : uint
+{
+ MaskNone = 0,
+ RobustnessPerComponentNV = 0x00000001,
+ RobustnessPerElementNV = 0x00000002,
+}
+
enum Op : uint
{
OpNop = 0,
@@ -1654,6 +1799,11 @@ enum Op : uint
OpUDotAccSatKHR = 4454,
OpSUDotAccSat = 4455,
OpSUDotAccSatKHR = 4455,
+ OpTypeCooperativeMatrixKHR = 4456,
+ OpCooperativeMatrixLoadKHR = 4457,
+ OpCooperativeMatrixStoreKHR = 4458,
+ OpCooperativeMatrixMulAddKHR = 4459,
+ OpCooperativeMatrixLengthKHR = 4460,
OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474,
@@ -1665,6 +1815,10 @@ enum Op : uint
OpImageBoxFilterQCOM = 4481,
OpImageBlockMatchSSDQCOM = 4482,
OpImageBlockMatchSADQCOM = 4483,
+ OpImageBlockMatchWindowSSDQCOM = 4500,
+ OpImageBlockMatchWindowSADQCOM = 4501,
+ OpImageBlockMatchGatherSSDQCOM = 4502,
+ OpImageBlockMatchGatherSADQCOM = 4503,
OpGroupIAddNonUniformAMD = 5000,
OpGroupFAddNonUniformAMD = 5001,
OpGroupFMinNonUniformAMD = 5002,
@@ -1676,6 +1830,11 @@ enum Op : uint
OpFragmentMaskFetchAMD = 5011,
OpFragmentFetchAMD = 5012,
OpReadClockKHR = 5056,
+ OpFinalizeNodePayloadsAMDX = 5075,
+ OpFinishWritingNodePayloadAMDX = 5078,
+ OpInitializeNodePayloadsAMDX = 5090,
+ OpGroupNonUniformQuadAllKHR = 5110,
+ OpGroupNonUniformQuadAnyKHR = 5111,
OpHitObjectRecordHitMotionNV = 5249,
OpHitObjectRecordHitWithIndexMotionNV = 5250,
OpHitObjectRecordMissMotionNV = 5251,
@@ -1714,6 +1873,8 @@ enum Op : uint
OpSetMeshOutputsEXT = 5295,
OpGroupNonUniformPartitionNV = 5296,
OpWritePackedPrimitiveIndices4x8NV = 5299,
+ OpFetchMicroTriangleVertexPositionNV = 5300,
+ OpFetchMicroTriangleVertexBarycentricNV = 5301,
OpReportIntersectionKHR = 5334,
OpReportIntersectionNV = 5334,
OpIgnoreIntersectionNV = 5335,
@@ -1742,6 +1903,7 @@ enum Op : uint
OpConvertUToSampledImageNV = 5395,
OpConvertSampledImageToUNV = 5396,
OpSamplerImageAddressingModeNV = 5397,
+ OpRawAccessChainNV = 5398,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,
@@ -1983,6 +2145,7 @@ enum Op : uint
OpTypeStructContinuedINTEL = 6090,
OpConstantCompositeContinuedINTEL = 6091,
OpSpecConstantCompositeContinuedINTEL = 6092,
+ OpCompositeConstructContinuedINTEL = 6096,
OpConvertFToBF16INTEL = 6116,
OpConvertBF16ToFINTEL = 6117,
OpControlBarrierArriveINTEL = 6142,
@@ -1995,6 +2158,8 @@ enum Op : uint
OpGroupLogicalAndKHR = 6406,
OpGroupLogicalOrKHR = 6407,
OpGroupLogicalXorKHR = 6408,
+ OpMaskedGatherINTEL = 6428,
+ OpMaskedScatterINTEL = 6429,
}
diff --git a/third_party/SPIRV-Headers/tests/CMakeLists.txt b/third_party/SPIRV-Headers/tests/CMakeLists.txt
index 6d8609028..ebf7e1244 100644
--- a/third_party/SPIRV-Headers/tests/CMakeLists.txt
+++ b/third_party/SPIRV-Headers/tests/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2015-2023 The Khronos Group Inc.
+# Copyright (c) 2015-2024 The Khronos Group Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and/or associated documentation files (the
@@ -24,13 +24,13 @@
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
-add_library(simple_test STATIC)
+add_library(spirv_headers_simple_test STATIC)
-target_sources(simple_test PRIVATE
+target_sources(spirv_headers_simple_test PRIVATE
example.cpp
)
-target_link_libraries(simple_test PRIVATE
+target_link_libraries(spirv_headers_simple_test PRIVATE
SPIRV-Headers::SPIRV-Headers
)
diff --git a/third_party/SPIRV-Headers/tests/example.cpp b/third_party/SPIRV-Headers/tests/example.cpp
index d79b62f22..1920e8038 100644
--- a/third_party/SPIRV-Headers/tests/example.cpp
+++ b/third_party/SPIRV-Headers/tests/example.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016 The Khronos Group Inc.
+// Copyright (c) 2016-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py b/third_party/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py
index c56780c1c..ccd843b94 100755
--- a/third_party/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/bin/generate_language_headers.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# Copyright (c) 2017-2020 Google LLC
+# Copyright (c) 2017-2024 Google LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and/or associated documentation files (the
@@ -32,7 +32,7 @@ import json
import os.path
import re
-DEFAULT_COPYRIGHT="""Copyright (c) 2020 The Khronos Group Inc.
+DEFAULT_COPYRIGHT="""Copyright (c) 2020-2024 The Khronos Group Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and/or associated documentation files (the
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py b/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py
index 8852d19c8..96ce008f6 100755
--- a/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeExtinstHeaders.py
@@ -27,3 +27,4 @@ mk_extinst('AMD_shader_trinary_minmax', 'extinst.spv-amd-shader-trinary-minmax.g
mk_extinst('NonSemanticDebugPrintf', 'extinst.nonsemantic.debugprintf.grammar.json')
mk_extinst('NonSemanticClspvReflection', 'extinst.nonsemantic.clspvreflection.grammar.json')
mk_extinst('NonSemanticDebugBreak', 'extinst.nonsemantic.debugbreak.grammar.json')
+mk_extinst('NonSemanticVkspReflection', 'extinst.nonsemantic.vkspreflection.grammar.json')
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders b/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders
index 7b4959ea0..853c46726 100755
--- a/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/bin/makeHeaders
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
+set -ex
+
python3 bin/makeExtinstHeaders.py
cd ../../include/spirv/unified1
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/header.cpp b/third_party/SPIRV-Headers/tools/buildHeaders/header.cpp
index fbae04451..d125a79aa 100644
--- a/third_party/SPIRV-Headers/tools/buildHeaders/header.cpp
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/header.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -169,29 +169,30 @@ namespace {
}
const std::string TPrinter::DocCopyright =
- "Copyright (c) 2014-2020 The Khronos Group Inc.\n"
- "\n"
- "Permission is hereby granted, free of charge, to any person obtaining a copy\n"
- "of this software and/or associated documentation files (the \"Materials\"),\n"
- "to deal in the Materials without restriction, including without limitation\n"
- "the rights to use, copy, modify, merge, publish, distribute, sublicense,\n"
- "and/or sell copies of the Materials, and to permit persons to whom the\n"
- "Materials are furnished to do so, subject to the following conditions:\n"
- "\n"
- "The above copyright notice and this permission notice shall be included in\n"
- "all copies or substantial portions of the Materials.\n"
- "\n"
- "MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS\n"
- "STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND\n"
- "HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ \n"
- "\n"
- "THE MATERIALS ARE PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n"
- "OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"
- "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n"
- "THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"
- "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n"
- "FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS\n"
- "IN THE MATERIALS.\n";
+R"(Copyright (c) 2014-2024 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and/or associated documentation files (the "Materials"),
+to deal in the Materials without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Materials, and to permit persons to whom the
+Materials are furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Materials.
+
+MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
+STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
+HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
+
+THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
+IN THE MATERIALS.
+)";
const std::string TPrinter::DocComment1 =
"This header is automatically generated by the same tool that creates\n"
@@ -574,13 +575,8 @@ namespace {
// C++ printer
class TPrinterCPP : public TPrinterCBase {
- private:
- void printPrologue(std::ostream& out) const override {
- TPrinterCBase::printPrologue(out);
- out << "namespace spv {\n\n";
- }
-
- void printEpilogue(std::ostream& out) const override {
+ protected:
+ void printMaskOperators(std::ostream& out, const std::string& specifiers) const {
const Json::Value& enums = spvRoot["spv"]["enum"];
out << "// Overload bitwise operators for mask bit combining\n\n";
@@ -593,20 +589,28 @@ namespace {
const auto typeName = opName + styleStr(enumMask);
// Overload operator|
- out << "inline " << typeName << " operator|(" << typeName << " a, " << typeName << " b) { return " <<
+ out << specifiers << " " << typeName << " operator|(" << typeName << " a, " << typeName << " b) { return " <<
typeName << "(unsigned(a) | unsigned(b)); }\n";
// Overload operator&
- out << "inline " << typeName << " operator&(" << typeName << " a, " << typeName << " b) { return " <<
+ out << specifiers << " " << typeName << " operator&(" << typeName << " a, " << typeName << " b) { return " <<
typeName << "(unsigned(a) & unsigned(b)); }\n";
// Overload operator^
- out << "inline " << typeName << " operator^(" << typeName << " a, " << typeName << " b) { return " <<
+ out << specifiers << " " << typeName << " operator^(" << typeName << " a, " << typeName << " b) { return " <<
typeName << "(unsigned(a) ^ unsigned(b)); }\n";
// Overload operator~
- out << "inline " << typeName << " operator~(" << typeName << " a) { return " <<
+ out << specifiers << " " << typeName << " operator~(" << typeName << " a) { return " <<
typeName << "(~unsigned(a)); }\n";
}
}
+ }
+ private:
+ void printPrologue(std::ostream& out) const override {
+ TPrinterCBase::printPrologue(out);
+ out << "namespace spv {\n\n";
+ }
+ void printEpilogue(std::ostream& out) const override {
+ printMaskOperators(out, "inline");
out << "\n} // end namespace spv\n\n";
out << "#endif // #ifndef spirv_" << headerGuardSuffix() << std::endl;
}
@@ -642,6 +646,11 @@ namespace {
// C++11 printer (uses enum classes)
class TPrinterCPP11 final : public TPrinterCPP {
private:
+ void printEpilogue(std::ostream& out) const override {
+ printMaskOperators(out, "constexpr");
+ out << "\n} // end namespace spv\n\n";
+ out << "#endif // #ifndef spirv_" << headerGuardSuffix() << std::endl;
+ }
std::string enumBeg(const std::string& s, enumStyle_t style) const override {
return std::string("enum class ") + s + styleStr(style) + " : unsigned {\n";
}
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/header.h b/third_party/SPIRV-Headers/tools/buildHeaders/header.h
index 1dd6e67b2..6854f80b5 100644
--- a/third_party/SPIRV-Headers/tools/buildHeaders/header.h
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/header.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2019 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp b/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp
index 67b5bce5c..34e097294 100644
--- a/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -36,8 +36,185 @@
#include "jsonToSpirv.h"
+namespace {
+// Returns true if the given string is a valid SPIR-V version.
+bool validSpirvVersionString(const std::string s) {
+ return
+ s == "1.0" ||
+ s == "1.1" ||
+ s == "1.2" ||
+ s == "1.3" ||
+ s == "1.4" ||
+ s == "1.5" ||
+ s == "1.6";
+}
+
+// Returns true if the given string is a valid version
+// specifier in the grammar file.
+bool validSpirvVersionStringSpecifier(const std::string s) {
+ return s == "None" || validSpirvVersionString(s);
+}
+} // anonymous namespace
+
namespace spv {
+bool IsLegacyDoublyEnabledInstruction(const std::string& instruction) {
+ static std::unordered_set<std::string> allowed = {
+ "OpSubgroupBallotKHR",
+ "OpSubgroupFirstInvocationKHR",
+ "OpSubgroupAllKHR",
+ "OpSubgroupAnyKHR",
+ "OpSubgroupAllEqualKHR",
+ "OpSubgroupReadInvocationKHR",
+ "OpTraceRayKHR",
+ "OpExecuteCallableKHR",
+ "OpConvertUToAccelerationStructureKHR",
+ "OpIgnoreIntersectionKHR",
+ "OpTerminateRayKHR",
+ "OpTypeRayQueryKHR",
+ "OpRayQueryInitializeKHR",
+ "OpRayQueryTerminateKHR",
+ "OpRayQueryGenerateIntersectionKHR",
+ "OpRayQueryConfirmIntersectionKHR",
+ "OpRayQueryProceedKHR",
+ "OpRayQueryGetIntersectionTypeKHR",
+ "OpGroupIAddNonUniformAMD",
+ "OpGroupFAddNonUniformAMD",
+ "OpGroupFMinNonUniformAMD",
+ "OpGroupUMinNonUniformAMD",
+ "OpGroupSMinNonUniformAMD",
+ "OpGroupFMaxNonUniformAMD",
+ "OpGroupUMaxNonUniformAMD",
+ "OpGroupSMaxNonUniformAMD",
+ "OpFragmentMaskFetchAMD",
+ "OpFragmentFetchAMD",
+ "OpImageSampleFootprintNV",
+ "OpGroupNonUniformPartitionNV",
+ "OpWritePackedPrimitiveIndices4x8NV",
+ "OpReportIntersectionNV",
+ "OpReportIntersectionKHR",
+ "OpIgnoreIntersectionNV",
+ "OpTerminateRayNV",
+ "OpTraceNV",
+ "OpTraceMotionNV",
+ "OpTraceRayMotionNV",
+ "OpTypeAccelerationStructureNV",
+ "OpTypeAccelerationStructureKHR",
+ "OpExecuteCallableNV",
+ "OpTypeCooperativeMatrixNV",
+ "OpCooperativeMatrixLoadNV",
+ "OpCooperativeMatrixStoreNV",
+ "OpCooperativeMatrixMulAddNV",
+ "OpCooperativeMatrixLengthNV",
+ "OpBeginInvocationInterlockEXT",
+ "OpEndInvocationInterlockEXT",
+ "OpIsHelperInvocationEXT",
+ "OpConstantFunctionPointerINTEL",
+ "OpFunctionPointerCallINTEL",
+ "OpAssumeTrueKHR",
+ "OpExpectKHR",
+ "OpLoopControlINTEL",
+ "OpAliasDomainDeclINTEL",
+ "OpAliasScopeDeclINTEL",
+ "OpAliasScopeListDeclINTEL",
+ "OpReadPipeBlockingINTEL",
+ "OpWritePipeBlockingINTEL",
+ "OpFPGARegINTEL",
+ "OpRayQueryGetRayTMinKHR",
+ "OpRayQueryGetRayFlagsKHR",
+ "OpRayQueryGetIntersectionTKHR",
+ "OpRayQueryGetIntersectionInstanceCustomIndexKHR",
+ "OpRayQueryGetIntersectionInstanceIdKHR",
+ "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR",
+ "OpRayQueryGetIntersectionGeometryIndexKHR",
+ "OpRayQueryGetIntersectionPrimitiveIndexKHR",
+ "OpRayQueryGetIntersectionBarycentricsKHR",
+ "OpRayQueryGetIntersectionFrontFaceKHR",
+ "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR",
+ "OpRayQueryGetIntersectionObjectRayDirectionKHR",
+ "OpRayQueryGetIntersectionObjectRayOriginKHR",
+ "OpRayQueryGetWorldRayDirectionKHR",
+ "OpRayQueryGetWorldRayOriginKHR",
+ "OpRayQueryGetIntersectionObjectToWorldKHR",
+ "OpRayQueryGetIntersectionWorldToObjectKHR",
+ "OpAtomicFAddEXT",
+ };
+ return allowed.count(instruction) != 0;
+}
+
+bool EnumValue::IsValid(OperandClass oc, const std::string& context) const
+{
+ bool result = true;
+ if (firstVersion.empty()) {
+ std::cerr << "Error: " << context << " " << name << " \"version\" must be set, probably to \"None\"" << std::endl;
+ result = false;
+ } else if (!validSpirvVersionStringSpecifier(firstVersion)) {
+ std::cerr << "Error: " << context << " " << name << " \"version\" is invalid: " << firstVersion << std::endl;
+ result = false;
+ }
+ if (!lastVersion.empty() && !validSpirvVersionString(lastVersion)) {
+ std::cerr << "Error: " << context << " " << name << " \"lastVersion\" is invalid: " << lastVersion << std::endl;
+ result = false;
+ }
+
+ // When a feature is introduced by an extension, the firstVersion is set to
+ // "None". There are three cases:
+ // - A new capability should be guarded/enabled by the extension
+ // - A new instruction should be:
+ // - Guarded/enabled by a new capability.
+ // - Not enabled by *both* a capability and an extension.
+ // There are many existing instructions that are already like this,
+ // and we grandparent them as allowed.
+ // - Other enums fall into two cases:
+ // 1. The enum is part of a new operand kind introduced by the extension.
+ // In this case we rely on transitivity: The use of the operand occurs
+ // in a new instruction that itself is guarded; or as the operand of
+ // another operand that itself is (recursively) guarded.
+ // 2. The enum is a new case in an existing operand kind. This case
+ // should be guarded by a capability. However, we do not check this
+ // here. Checking it requires more context than we have here.
+ if (oc == OperandOpcode) {
+ const bool instruction_unusable =
+ (firstVersion == "None") && extensions.empty() && capabilities.empty();
+ if (instruction_unusable) {
+ std::cerr << "Error: " << context << " " << name << " is not usable: "
+ << "its version is set to \"None\", and it is not enabled by a "
+ << "capability or extension. Guard it with a capability."
+ << std::endl;
+ result = false;
+ }
+ // Complain if an instruction is not in any core version and also enabled by
+ // both an extension and a capability.
+ // It's important to check the "not in any core version" case, because,
+ // for example, OpTerminateInvocation is in SPIR-V 1.6 *and* enabled by an
+ // extension, and guarded by the Shader capability.
+ const bool instruction_doubly_enabled = (firstVersion == "None") &&
+ !extensions.empty() &&
+ !capabilities.empty();
+ if (instruction_doubly_enabled && !IsLegacyDoublyEnabledInstruction(name)) {
+ std::cerr << "Error: " << context << " " << name << " is doubly-enabled: "
+ << "it is enabled by both a capability and an extension. "
+ << "Guard it with a capability only." << std::endl;
+ result = false;
+ }
+ }
+ if (oc == OperandCapability) {
+ // If capability X lists capabilities Y and Z, then Y and Z are *enabled*
+ // when X is enabled. They are not *guards* on X's use.
+ // Only versions and extensions can guard a capability.
+ const bool capability_unusable =
+ (firstVersion == "None") && extensions.empty();
+ if (capability_unusable) {
+ std::cerr << "Error: " << context << " " << name << " is not usable: "
+ << "its version is set to \"None\", and it is not enabled by "
+ << "an extension. Guard it with an extension." << std::endl;
+ result = false;
+ }
+ }
+
+ return result;
+}
+
// The set of objects that hold all the instruction/operand
// parameterization information.
InstructionValues InstructionDesc;
@@ -88,6 +265,15 @@ EnumValues RayQueryCommittedIntersectionTypeParams;
EnumValues RayQueryCandidateIntersectionTypeParams;
EnumValues FragmentShadingRateParams;
EnumValues PackedVectorFormatParams;
+EnumValues CooperativeMatrixOperandsParams;
+EnumValues CooperativeMatrixLayoutParams;
+EnumValues CooperativeMatrixUseParams;
+EnumValues InitializationModeQualifierParams;
+EnumValues HostAccessQualifierParams;
+EnumValues LoadCacheControlParams;
+EnumValues StoreCacheControlParams;
+EnumValues NamedMaximumNumberOfRegistersParams;
+EnumValues RawAccessChainOperandsParams;
std::pair<bool, std::string> ReadFile(const std::string& path)
{
@@ -158,6 +344,8 @@ ClassOptionality ToOperandClassAndOptionality(const std::string& operandKind, co
type = OperandLiteralNumber;
} else if (operandKind == "LiteralContextDependentNumber") {
type = OperandAnySizeLiteralNumber;
+ } else if (operandKind == "LiteralFloat") {
+ type = OperandLiteralNumber;
} else if (operandKind == "SourceLanguage") {
type = OperandSource;
} else if (operandKind == "ExecutionModel") {
@@ -234,6 +422,24 @@ ClassOptionality ToOperandClassAndOptionality(const std::string& operandKind, co
type = OperandFragmentShadingRate;
} else if (operandKind == "PackedVectorFormat") {
type = OperandPackedVectorFormat;
+ } else if (operandKind == "CooperativeMatrixOperands") {
+ type = OperandCooperativeMatrixOperands;
+ } else if (operandKind == "CooperativeMatrixLayout") {
+ type = OperandCooperativeMatrixLayout;
+ } else if (operandKind == "CooperativeMatrixUse") {
+ type = OperandCooperativeMatrixUse;
+ } else if (operandKind == "InitializationModeQualifier") {
+ type = OperandInitializationModeQualifier;
+ } else if (operandKind == "HostAccessQualifier") {
+ type = OperandHostAccessQualifier;
+ } else if (operandKind == "LoadCacheControl") {
+ type = OperandLoadCacheControl;
+ } else if (operandKind == "StoreCacheControl") {
+ type = OperandStoreCacheControl;
+ } else if (operandKind == "NamedMaximumNumberOfRegisters") {
+ type = OperandNamedMaximumNumberOfRegisters;
+ } else if (operandKind == "RawAccessChainOperands") {
+ type = OperandRawAccessChainOperands;
}
if (type == OperandNone) {
@@ -273,6 +479,8 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
return;
initialized = true;
+ size_t errorCount = 0;
+
// Read the JSON grammar file.
bool fileReadOk = false;
std::string content;
@@ -326,8 +534,10 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
for (const auto& printingClass : printingClasses) {
if (printingClass["tag"].asString().size() > 0)
tags.insert(printingClass["tag"].asString()); // just for error checking
- else
+ else {
std::cerr << "Error: each instruction_printing_class requires a non-empty \"tag\"" << std::endl;
+ std::exit(1);
+ }
if (buildingHeaders || printingClass["tag"].asString() != "@exclude") {
InstructionPrintingClasses.push_back({printingClass["tag"].asString(),
printingClass["heading"].asString()});
@@ -343,6 +553,7 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
if (printingClass.size() == 0) {
std::cerr << "Error: " << inst["opname"].asString()
<< " requires a non-empty printing \"class\" tag" << std::endl;
+ std::exit(1);
}
if (!buildingHeaders && printingClass == "@exclude")
continue;
@@ -350,6 +561,7 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
std::cerr << "Error: " << inst["opname"].asString()
<< " requires a \"class\" declared as a \"tag\" in \"instruction printing_class\""
<< std::endl;
+ std::exit(1);
}
const auto opcode = inst["opcode"].asUInt();
const std::string name = inst["opname"].asString();
@@ -387,12 +599,15 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
std::move(caps), std::move(version), std::move(lastVersion), std::move(exts),
std::move(operands))),
printingClass, defTypeId, defResultId);
+ if (!InstructionDesc.back().IsValid(OperandOpcode, "instruction")) {
+ errorCount++;
+ }
}
// Specific additional context-dependent operands
// Populate dest with EnumValue objects constructed from source.
- const auto populateEnumValues = [&getCaps,&getExts](EnumValues* dest, const Json::Value& source, bool bitEnum) {
+ const auto populateEnumValues = [&getCaps,&getExts,&errorCount](EnumValues* dest, const Json::Value& source, bool bitEnum) {
// A lambda for determining the numeric value to be used for a given
// enumerant in JSON form, and whether that value is a 0 in a bitfield.
auto getValue = [&bitEnum](const Json::Value& enumerant) {
@@ -451,12 +666,22 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
}
};
- const auto establishOperandClass = [&populateEnumValues](
+ const auto establishOperandClass = [&populateEnumValues,&errorCount](
const std::string& enumName, spv::OperandClass operandClass,
spv::EnumValues* enumValues, const Json::Value& operandEnum, const std::string& category) {
assert(category == "BitEnum" || category == "ValueEnum");
bool bitEnum = (category == "BitEnum");
+ if (!operandEnum["version"].empty()) {
+ std::cerr << "Error: container for " << enumName << " operand_kind must not have a version field" << std::endl;
+ errorCount++;
+ }
populateEnumValues(enumValues, operandEnum, bitEnum);
+ const std::string errContext = "enum " + enumName;
+ for (const auto& e: *enumValues) {
+ if (!e.IsValid(operandClass, errContext)) {
+ errorCount++;
+ }
+ }
OperandClassParams[operandClass].set(enumName, enumValues, bitEnum);
};
@@ -544,8 +769,30 @@ void jsonToSpirv(const std::string& jsonPath, bool buildingHeaders)
establishOperandClass(enumName, OperandFragmentShadingRate, &FragmentShadingRateParams, operandEnum, category);
} else if (enumName == "PackedVectorFormat") {
establishOperandClass(enumName, OperandPackedVectorFormat, &PackedVectorFormatParams, operandEnum, category);
+ } else if (enumName == "CooperativeMatrixOperands") {
+ establishOperandClass(enumName, OperandCooperativeMatrixOperands, &CooperativeMatrixOperandsParams, operandEnum, category);
+ } else if (enumName == "CooperativeMatrixLayout") {
+ establishOperandClass(enumName, OperandCooperativeMatrixLayout, &CooperativeMatrixLayoutParams, operandEnum, category);
+ } else if (enumName == "CooperativeMatrixUse") {
+ establishOperandClass(enumName, OperandCooperativeMatrixUse, &CooperativeMatrixUseParams, operandEnum, category);
+ } else if (enumName == "InitializationModeQualifier") {
+ establishOperandClass(enumName, OperandInitializationModeQualifier, &InitializationModeQualifierParams, operandEnum, category);
+ } else if (enumName == "HostAccessQualifier") {
+ establishOperandClass(enumName, OperandHostAccessQualifier, &HostAccessQualifierParams, operandEnum, category);
+ } else if (enumName == "LoadCacheControl") {
+ establishOperandClass(enumName, OperandLoadCacheControl, &LoadCacheControlParams, operandEnum, category);
+ } else if (enumName == "StoreCacheControl") {
+ establishOperandClass(enumName, OperandStoreCacheControl, &StoreCacheControlParams, operandEnum, category);
+ } else if (enumName == "NamedMaximumNumberOfRegisters") {
+ establishOperandClass(enumName, OperandNamedMaximumNumberOfRegisters, &NamedMaximumNumberOfRegistersParams, operandEnum, category);
+ } else if (enumName == "RawAccessChainOperands") {
+ establishOperandClass(enumName, OperandRawAccessChainOperands, &RawAccessChainOperandsParams, operandEnum, category);
}
}
+
+ if (errorCount > 0) {
+ std::exit(1);
+ }
}
}; // end namespace spv
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h b/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h
index 3be645687..c8de68f54 100644
--- a/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/jsonToSpirv.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2020 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
@@ -96,6 +96,15 @@ enum OperandClass {
OperandQuantizationModes,
OperandOverflowModes,
OperandPackedVectorFormat,
+ OperandCooperativeMatrixOperands,
+ OperandCooperativeMatrixLayout,
+ OperandCooperativeMatrixUse,
+ OperandInitializationModeQualifier,
+ OperandHostAccessQualifier,
+ OperandLoadCacheControl,
+ OperandStoreCacheControl,
+ OperandNamedMaximumNumberOfRegisters,
+ OperandRawAccessChainOperands,
OperandOpcode,
@@ -184,6 +193,7 @@ public:
iterator begin() { return values.begin(); }
iterator end() { return values.end(); }
+ EValue& back() { return values.back(); }
private:
ContainerType values;
@@ -216,6 +226,10 @@ public:
Extensions extensions;
OperandParameters operands;
const char* desc;
+
+ // Returns true if this enum is valid, in isolation.
+ // Otherwise emits a diagnostic to std::cerr and returns false.
+ bool IsValid(OperandClass oc, const std::string& context) const;
};
using EnumValues = EnumValuesContainer<EnumValue>;
diff --git a/third_party/SPIRV-Headers/tools/buildHeaders/main.cpp b/third_party/SPIRV-Headers/tools/buildHeaders/main.cpp
index 9a5971408..6e6a03b34 100644
--- a/third_party/SPIRV-Headers/tools/buildHeaders/main.cpp
+++ b/third_party/SPIRV-Headers/tools/buildHeaders/main.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2019 The Khronos Group Inc.
+// Copyright (c) 2014-2024 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and/or associated documentation files (the "Materials"),
diff --git a/third_party/SPIRV-Tools/.bazelrc b/third_party/SPIRV-Tools/.bazelrc
new file mode 100644
index 000000000..79ad59480
--- /dev/null
+++ b/third_party/SPIRV-Tools/.bazelrc
@@ -0,0 +1,7 @@
+# Enable Bzlmod for every Bazel command
+common --enable_bzlmod
+
+build --enable_platform_specific_config
+build:linux --cxxopt=-std=c++17
+build:macos --cxxopt=-std=c++17
+build:windows --cxxopt=/std:c++17
diff --git a/third_party/SPIRV-Tools/.bazelversion b/third_party/SPIRV-Tools/.bazelversion
index 28cbf7c0a..a8907c025 100644
--- a/third_party/SPIRV-Tools/.bazelversion
+++ b/third_party/SPIRV-Tools/.bazelversion
@@ -1 +1 @@
-5.0.0 \ No newline at end of file
+7.0.2
diff --git a/third_party/SPIRV-Tools/.github/dependabot.yml b/third_party/SPIRV-Tools/.github/dependabot.yml
new file mode 100644
index 000000000..dca857a3d
--- /dev/null
+++ b/third_party/SPIRV-Tools/.github/dependabot.yml
@@ -0,0 +1,25 @@
+# Copyright 2023 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: 2
+updates:
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: daily
+ groups:
+ github-actions:
+ patterns:
+ - "*"
+ open-pull-requests-limit: 3
diff --git a/third_party/SPIRV-Tools/.github/workflows/autoroll.yml b/third_party/SPIRV-Tools/.github/workflows/autoroll.yml
index 4520309d4..ed33622be 100644
--- a/third_party/SPIRV-Tools/.github/workflows/autoroll.yml
+++ b/third_party/SPIRV-Tools/.github/workflows/autoroll.yml
@@ -16,14 +16,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
# Checkout the depot tools they are needed by roll_deps.sh
- name: Checkout depot tools
run: git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- name: Update PATH
- run: echo "./depot_tools" >> $GITHUB_PATH
+ run: echo "$(pwd)/depot_tools" >> $GITHUB_PATH
- name: Download dependencies
run: python3 utils/git-sync-deps
@@ -47,6 +47,10 @@ jobs:
if: steps.update_dependencies.outputs.changed == 'true'
run: |
git push --force --set-upstream origin roll_deps
- gh pr create --label 'kokoro:run' --base main -f -r s-perron
+ # Create a PR. If it aready exists, the command fails, so ignore the return code.
+ gh pr create --base main -f || true
+ # Add the 'kokoro:run' label so that the kokoro tests will be run.
+ gh pr edit --add-label 'kokoro:run'
+ gh pr merge --auto --squash
env:
GITHUB_TOKEN: ${{ github.token }}
diff --git a/third_party/SPIRV-Tools/.github/workflows/bazel.yml b/third_party/SPIRV-Tools/.github/workflows/bazel.yml
index 88700c44c..43c99d667 100644
--- a/third_party/SPIRV-Tools/.github/workflows/bazel.yml
+++ b/third_party/SPIRV-Tools/.github/workflows/bazel.yml
@@ -13,30 +13,22 @@ jobs:
timeout-minutes: 120
strategy:
matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
+ os: [ubuntu-latest, macos-latest, windows-2019]
runs-on: ${{matrix.os}}
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
with:
fetch-depth: '0'
- name: Download dependencies
run: python3 utils/git-sync-deps
- name: Mount Bazel cache
- uses: actions/cache@v3
+ uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ~/.bazel/cache
key: bazel-cache-${{ runner.os }}
- - name: Build All (Windows)
- if: ${{matrix.os == 'windows-latest' }}
- run: bazel --output_user_root=~/.bazel/cache build --cxxopt=/std:c++17 //...
- - name: Test All (Windows)
- if: ${{matrix.os == 'windows-latest' }}
- run: bazel --output_user_root=~/.bazel/cache test --cxxopt=/std:c++17 //...
- - name: Build All (Linux, MacOS)
- if: ${{ matrix.os != 'windows-latest' }}
- run: bazel --output_user_root=~/.bazel/cache build --cxxopt=-std=c++17 //...
- - name: Test All (Linux, MacOS)
- if: ${{ matrix.os != 'windows-latest' }}
- run: bazel --output_user_root=~/.bazel/cache test --cxxopt=-std=c++17 //...
+ - name: Build All
+ run: bazel --output_user_root=~/.bazel/cache build //...
+ - name: Test All
+ run: bazel --output_user_root=~/.bazel/cache test //...
diff --git a/third_party/SPIRV-Tools/.github/workflows/ios.yml b/third_party/SPIRV-Tools/.github/workflows/ios.yml
new file mode 100644
index 000000000..feb64a775
--- /dev/null
+++ b/third_party/SPIRV-Tools/.github/workflows/ios.yml
@@ -0,0 +1,30 @@
+name: iOS
+permissions:
+ contents: read
+
+on: [push, pull_request, workflow_dispatch]
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ macos-12, macos-13 ]
+ steps:
+ - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
+ - uses: lukka/get-cmake@4931ab1fc1604964c055eb330edb3f6b26ba0cfa # v3.29.2
+ - name: Download dependencies
+ run: python3 utils/git-sync-deps
+ # NOTE: The MacOS SDK ships universal binaries. CI should reflect this.
+ - name: Configure Universal Binary for iOS
+ run: |
+ cmake -S . -B build \
+ -D CMAKE_BUILD_TYPE=Debug \
+ -D CMAKE_SYSTEM_NAME=iOS \
+ "-D CMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
+ -G Ninja
+ env:
+ # Linker warnings as errors
+ LDFLAGS: -Wl,-fatal_warnings
+ - run: cmake --build build
+ - run: cmake --install build --prefix /tmp
diff --git a/third_party/SPIRV-Tools/.github/workflows/release.yml b/third_party/SPIRV-Tools/.github/workflows/release.yml
index ada943169..583c8f1fd 100644
--- a/third_party/SPIRV-Tools/.github/workflows/release.yml
+++ b/third_party/SPIRV-Tools/.github/workflows/release.yml
@@ -6,13 +6,14 @@ on:
push:
tags:
- 'v[0-9]+.[0-9]+'
+ - 'vulkan-sdk-[0-9]+.[0-9]+.[0-9]+.[0-9]+'
- '!v[0-9]+.[0-9]+.rc*'
jobs:
prepare-release-job:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- name: Prepare CHANGELOG for version
run: |
python utils/generate_changelog.py CHANGES "${{ github.ref_name }}" VERSION_CHANGELOG
diff --git a/third_party/SPIRV-Tools/.github/workflows/scorecard.yml b/third_party/SPIRV-Tools/.github/workflows/scorecard.yml
new file mode 100644
index 000000000..adcfa7677
--- /dev/null
+++ b/third_party/SPIRV-Tools/.github/workflows/scorecard.yml
@@ -0,0 +1,53 @@
+name: Scorecard supply-chain security
+on:
+ # For Branch-Protection check. Only the default branch is supported. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
+ branch_protection_rule:
+ # To guarantee Maintained check is occasionally updated. See
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
+ schedule:
+ - cron: '36 17 * * 5'
+ push:
+ branches: [ "main" ]
+
+# Declare default permissions as read only.
+permissions: read-all
+
+jobs:
+ analysis:
+ name: Scorecard analysis
+ runs-on: ubuntu-latest
+ permissions:
+ security-events: write # to upload the results to code-scanning dashboard
+ id-token: write # to publish results and get a badge
+
+ steps:
+ - name: "Checkout code"
+ uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
+ with:
+ persist-credentials: false
+
+ - name: "Run analysis"
+ uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ # To enable Branch-Protection uncomment the `repo_token` line below
+ # To create the Fine-grained PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-fine-grained-pat-optional.
+ # repo_token: ${{ secrets.SCORECARD_TOKEN }}
+ publish_results: true # allows the repo to include the Scorecard badge
+
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
+ # format to the repository Actions tab.
+ - name: "Upload artifact"
+ uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
+ with:
+ sarif_file: results.sarif
diff --git a/third_party/SPIRV-Tools/.github/workflows/wasm.yml b/third_party/SPIRV-Tools/.github/workflows/wasm.yml
index 62c9af384..6807b3d1e 100644
--- a/third_party/SPIRV-Tools/.github/workflows/wasm.yml
+++ b/third_party/SPIRV-Tools/.github/workflows/wasm.yml
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
+ - uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
with:
fetch-depth: '0'
- name: Build web
diff --git a/third_party/SPIRV-Tools/.gitignore b/third_party/SPIRV-Tools/.gitignore
index ec709ba79..e85cea95d 100644
--- a/third_party/SPIRV-Tools/.gitignore
+++ b/third_party/SPIRV-Tools/.gitignore
@@ -4,6 +4,7 @@
compile_commands.json
/build*/
/buildtools/
+/external/abseil_cpp/
/external/googletest
/external/SPIRV-Headers
/external/spirv-headers
@@ -22,6 +23,7 @@ bazel-out
bazel-spirv-tools
bazel-SPIRV-Tools
bazel-testlogs
+MODULE.bazel.lock
# Vim
[._]*.s[a-w][a-z]
diff --git a/third_party/SPIRV-Tools/Android.bp b/third_party/SPIRV-Tools/Android.bp
index a760d5d96..65dd4d956 100644
--- a/third_party/SPIRV-Tools/Android.bp
+++ b/third_party/SPIRV-Tools/Android.bp
@@ -71,6 +71,7 @@ genrule {
"spv-amd-shader-explicit-vertex-parameter.insts.inc",
"spv-amd-shader-trinary-minmax.insts.inc",
"nonsemantic.clspvreflection.insts.inc",
+ "nonsemantic.vkspreflection.insts.inc",
"nonsemantic.shader.debuginfo.100.insts.inc",
],
srcs: [
@@ -84,6 +85,7 @@ genrule {
":swiftshader_spirv_headers_unified1_extinst.spv-amd-shader-explicit-vertex-parameter.grammar.json",
":swiftshader_spirv_headers_unified1_extinst.spv-amd-shader-trinary-minmax.grammar.json",
":swiftshader_spirv_headers_unified1_extinst.nonsemantic.clspvreflection.grammar.json",
+ ":swiftshader_spirv_headers_unified1_extinst.nonsemantic.vkspreflection.grammar.json",
":swiftshader_spirv_headers_unified1_extinst.nonsemantic.shader.debuginfo.100.grammar.json",
],
tool_files: ["utils/generate_grammar_tables.py"],
@@ -99,6 +101,7 @@ genrule {
"$(location) --extinst-opencl-grammar=$(location :swiftshader_spirv_headers_unified1_extinst.opencl.std.100.grammar.json) --opencl-insts-output=$(location opencl.std.insts.inc) --output-language=c++; "+
"$(location) --extinst-glsl-grammar=$(location :swiftshader_spirv_headers_unified1_extinst.glsl.std.450.grammar.json) --glsl-insts-output=$(location glsl.std.450.insts.inc) --output-language=c++; " +
"$(location) --extinst-vendor-grammar=$(location :swiftshader_spirv_headers_unified1_extinst.nonsemantic.clspvreflection.grammar.json) --vendor-insts-output=$(location nonsemantic.clspvreflection.insts.inc) --vendor-operand-kind-prefix=; " +
+ "$(location) --extinst-vendor-grammar=$(location :swiftshader_spirv_headers_unified1_extinst.nonsemantic.vkspreflection.grammar.json) --vendor-insts-output=$(location nonsemantic.vkspreflection.insts.inc) --vendor-operand-kind-prefix=; " +
"$(location) --extinst-vendor-grammar=$(location :swiftshader_spirv_headers_unified1_extinst.nonsemantic.shader.debuginfo.100.grammar.json) --vendor-insts-output=$(location nonsemantic.shader.debuginfo.100.insts.inc) --vendor-operand-kind-prefix=SHDEBUG100_; "
}
diff --git a/third_party/SPIRV-Tools/BUILD.bazel b/third_party/SPIRV-Tools/BUILD.bazel
index ae7f35c6d..48a688e7c 100644
--- a/third_party/SPIRV-Tools/BUILD.bazel
+++ b/third_party/SPIRV-Tools/BUILD.bazel
@@ -58,6 +58,8 @@ generate_vendor_tables(extension = "debuginfo")
generate_vendor_tables(extension = "nonsemantic.clspvreflection")
+generate_vendor_tables(extension = "nonsemantic.vkspreflection")
+
generate_vendor_tables(
extension = "opencl.debuginfo.100",
operand_kind_prefix = "CLDEBUG100_",
@@ -94,7 +96,7 @@ genrule(
outs = ["generators.inc"],
cmd = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
cmd_bat = "$(location :generate_registry_tables) --xml=$(location @spirv_headers//:spirv_xml_registry) --generator-output=$(location generators.inc)",
- exec_tools = [":generate_registry_tables"],
+ tools = [":generate_registry_tables"],
)
py_binary(
@@ -108,10 +110,8 @@ genrule(
outs = ["build-version.inc"],
cmd = "SOURCE_DATE_EPOCH=0 $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
cmd_bat = "set SOURCE_DATE_EPOCH=0 && $(location :update_build_version) $(location CHANGES) $(location build-version.inc)",
- # This is explicitly tools and not exec_tools because we run it locally (on the host platform) instead of
- # (potentially remotely) on the execution platform.
- tools = [":update_build_version"],
local = True,
+ tools = [":update_build_version"],
)
# Libraries
@@ -146,15 +146,16 @@ cc_library(
":gen_extinst_lang_headers_OpenCLDebugInfo100",
":gen_glsl_tables_unified1",
":gen_opencl_tables_unified1",
- ":generators_inc",
":gen_vendor_tables_debuginfo",
":gen_vendor_tables_nonsemantic_clspvreflection",
+ ":gen_vendor_tables_nonsemantic_vkspreflection",
":gen_vendor_tables_nonsemantic_shader_debuginfo_100",
":gen_vendor_tables_opencl_debuginfo_100",
":gen_vendor_tables_spv_amd_gcn_shader",
":gen_vendor_tables_spv_amd_shader_ballot",
":gen_vendor_tables_spv_amd_shader_explicit_vertex_parameter",
":gen_vendor_tables_spv_amd_shader_trinary_minmax",
+ ":generators_inc",
],
hdrs = [
"include/spirv-tools/libspirv.h",
@@ -307,17 +308,17 @@ cc_binary(
cc_binary(
name = "spirv-objdump",
srcs = [
- "tools/objdump/objdump.cpp",
"tools/objdump/extract_source.cpp",
"tools/objdump/extract_source.h",
+ "tools/objdump/objdump.cpp",
],
copts = COMMON_COPTS,
visibility = ["//visibility:public"],
deps = [
- ":tools_io",
- ":tools_util",
":spirv_tools_internal",
":spirv_tools_opt_internal",
+ ":tools_io",
+ ":tools_util",
"@spirv_headers//:spirv_cpp_headers",
],
)
@@ -428,7 +429,7 @@ cc_library(
copts = TEST_COPTS,
deps = [
":spirv_tools_internal",
- "@com_google_googletest//:gtest",
+ "@googletest//:gtest",
],
)
@@ -439,23 +440,25 @@ cc_library(
name = "base_{testcase}_test".format(testcase = f[len("test/"):-len("_test.cpp")]),
size = "small",
srcs = [f],
- copts = TEST_COPTS + ['-DTESTING'],
+ copts = TEST_COPTS + ["-DTESTING"],
linkstatic = 1,
target_compatible_with = {
"test/timer_test.cpp": incompatible_with(["@bazel_tools//src/conditions:windows"]),
}.get(f, []),
deps = [
+ "tools_util",
":spirv_tools_internal",
":test_lib",
- "tools_util",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
- ["test/*_test.cpp", "test/tools/*_test.cpp"],
+ [
+ "test/*_test.cpp",
+ "test/tools/*_test.cpp",
+ ],
exclude = [
"test/cpp_interface_test.cpp",
- "test/log_test.cpp",
"test/pch_test.cpp",
],
)]
@@ -467,8 +470,8 @@ cc_test(
linkstatic = 1,
deps = [
":spirv_tools_opt_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
"@spirv_headers//:spirv_cpp11_headers",
],
)
@@ -481,21 +484,8 @@ cc_test(
linkstatic = 1,
deps = [
":spirv_tools_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
- ],
-)
-
-cc_test(
- name = "base_log_test",
- size = "small",
- srcs = ["test/log_test.cpp"],
- copts = TEST_COPTS,
- linkstatic = 1,
- deps = [
- ":spirv_tools_opt_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
)
@@ -521,8 +511,8 @@ cc_library(
linkstatic = 1,
deps = [
":link_test_lib",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
["test/link/*_test.cpp"],
@@ -538,8 +528,8 @@ cc_library(
":spirv_tools",
":spirv_tools_lint_internal",
":spirv_tools_opt_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
["test/lint/*_test.cpp"],
@@ -563,7 +553,7 @@ cc_library(
":spirv_tools_internal",
":spirv_tools_opt_internal",
"@com_google_effcee//:effcee",
- "@com_google_googletest//:gtest",
+ "@googletest//:gtest",
],
)
@@ -579,8 +569,8 @@ cc_library(
":spirv_tools_opt_internal",
":test_lib",
"@com_google_effcee//:effcee",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(["test/opt/*_test.cpp"])]
@@ -593,8 +583,8 @@ cc_library(
deps = [
":opt_test_lib",
":spirv_tools_opt_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
["test/opt/dominator_tree/*.cpp"],
@@ -612,8 +602,8 @@ cc_library(
":spirv_tools",
":spirv_tools_opt_internal",
"@com_google_effcee//:effcee",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
["test/opt/loop_optimizations/*.cpp"],
@@ -634,7 +624,7 @@ cc_library(
":spirv_tools_reduce",
":test_lib",
":tools_io",
- "@com_google_googletest//:gtest",
+ "@googletest//:gtest",
],
)
@@ -649,7 +639,7 @@ cc_library(
":spirv_tools_internal",
":spirv_tools_opt_internal",
":spirv_tools_reduce",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest_main",
],
) for f in glob(["test/reduce/*_test.cpp"])]
@@ -661,8 +651,8 @@ cc_library(
linkstatic = 1,
deps = [
":spirv_tools_internal",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(["test/util/*_test.cpp"])]
@@ -693,8 +683,8 @@ cc_library(
":spirv_tools_internal",
":test_lib",
":val_test_lib",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
) for f in glob(
["test/val/val_*_test.cpp"],
@@ -715,8 +705,8 @@ cc_test(
":spirv_tools_internal",
":test_lib",
":val_test_lib",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
)
@@ -732,7 +722,7 @@ cc_test(
deps = [
":test_lib",
":val_test_lib",
- "@com_google_googletest//:gtest",
- "@com_google_googletest//:gtest_main",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
],
)
diff --git a/third_party/SPIRV-Tools/BUILD.gn b/third_party/SPIRV-Tools/BUILD.gn
index e8622a133..4848fddd0 100644
--- a/third_party/SPIRV-Tools/BUILD.gn
+++ b/third_party/SPIRV-Tools/BUILD.gn
@@ -331,6 +331,10 @@ spvtools_vendor_tables = [
"...nil...",
],
[
+ "nonsemantic.vkspreflection",
+ "...nil...",
+ ],
+ [
"nonsemantic.shader.debuginfo.100",
"SHDEBUG100_",
],
@@ -696,6 +700,8 @@ static_library("spvtools_opt") {
"source/opt/interface_var_sroa.h",
"source/opt/interp_fixup_pass.cpp",
"source/opt/interp_fixup_pass.h",
+ "source/opt/invocation_interlock_placement_pass.cpp",
+ "source/opt/invocation_interlock_placement_pass.h",
"source/opt/ir_builder.h",
"source/opt/ir_context.cpp",
"source/opt/ir_context.h",
@@ -738,6 +744,8 @@ static_library("spvtools_opt") {
"source/opt/mem_pass.h",
"source/opt/merge_return_pass.cpp",
"source/opt/merge_return_pass.h",
+ "source/opt/modify_maximal_reconvergence.cpp",
+ "source/opt/modify_maximal_reconvergence.h",
"source/opt/module.cpp",
"source/opt/module.h",
"source/opt/null_pass.h",
@@ -792,7 +800,11 @@ static_library("spvtools_opt") {
"source/opt/strip_nonsemantic_info_pass.h",
"source/opt/struct_cfg_analysis.cpp",
"source/opt/struct_cfg_analysis.h",
+ "source/opt/switch_descriptorset_pass.cpp",
+ "source/opt/switch_descriptorset_pass.h",
"source/opt/tree_iterator.h",
+ "source/opt/trim_capabilities_pass.cpp",
+ "source/opt/trim_capabilities_pass.h",
"source/opt/type_manager.cpp",
"source/opt/type_manager.h",
"source/opt/types.cpp",
diff --git a/third_party/SPIRV-Tools/CHANGES b/third_party/SPIRV-Tools/CHANGES
index dbe31a0c0..102703a87 100644
--- a/third_party/SPIRV-Tools/CHANGES
+++ b/third_party/SPIRV-Tools/CHANGES
@@ -1,5 +1,150 @@
Revision history for SPIRV-Tools
+v2024.2 2024-04-22
+ - General
+ - Add SPIRV_TOOLS_EXPORT to public C++ API (#5591)
+ - Use bazel 7 and bzlmod (#5601)
+ - Optimizer
+ - opt: add GroupNonUniformPartitionedNV capability to trim pass (#5648)
+ - Fix rebuilding types with circular references. (#5637)
+ - Add AliasedPointer decoration (#5635)
+ - add support for vulkan-shader-profiler external passes (#5512)
+ - Validator
+ - A fix to support of SPV_QCOM_image_processing2 (#5646)
+ - spirv-val: Add Vulkan check for Rect Dim in OpTypeImage (#5644)
+ - Validate duplicate decorations and execution modes (#5641)
+ - Validator: Support SPV_NV_raw_access_chains (#5568)
+
+v2024.1 2024-03-06
+ - General
+ - Add tooling support for SPV_KHR_maximal_reconvergence (#5542)
+ - Add support for SPV_KHR_float_controls2 (#5543)
+ - SPV_KHR_quad_control (#5547)
+ - Fold 64-bit int operations (#5561)
+ - update image enum tests to remove Kernel capability (#5562)
+ - Support operand kind for SPV_INTEL_maximum_registers (#5580)
+ - SPV_NV_shader_atomic_fp16_vector (#5581)
+ - Support for SPV_QCOM_image_processing2 (#5582)
+ - Fix access chain struct checks (#5592)
+ - Optimizer
+ - opt: add Int16 and Float16 to capability trim pass (#5519)
+ - Add preserver-interface option to spirv-opt (#5524)
+ - spirv-opt: Fix OpCompositeExtract relaxation with struct operands (#5536)
+ - opt: Add VulkanMemoryModelDeviceScope to trim (#5544)
+ - opt: Add TrimCapabilities pass to spirv-opt tool (#5545)
+ - Add modify-maximal-reconvergence to spirv-opt help (#5546)
+ - opt: add SPV_EXT_mesh_shader to opt allowlist (#5551)
+ - opt: Add OpEntryPoint to DescriptorScalarReplacement pass (#5553)
+ - opt: prevent meld to merge block with MaximalReconvergence (#5557)
+ - [OPT] Use new instruction folder for for all opcodes in spec consti folding (#5569)
+ - [OPT] Identify arrays with unknown length in copy prop arrays (#5570)
+ - [OPT] Add removed unused interface var pass to legalization passes (#5579)
+ - Validator
+ - spirv-val: Re-enable OpControlBarrier VU (#5527)
+ - spirv-val: Add Mesh Primitive Built-In validaiton (#5529)
+ - spirv-val: Validate PhysicalStorageBuffer Stage Interface (#5539)
+ - spirv-val: Multiple interface var with same SC (#5528)
+ - spirv-val: Revert Validate PhysicalStorageBuffer Stage Interface (#5575)
+ - spirv-val: Make Constant evaluation consistent (#5587)
+
+v2023.6 2023-12-18
+ - General
+ - update_build_version.py produce deterministic header. (#5426)
+ - Support missing git in update_build_version.py (#5473)
+ - Optimizer
+ - Add ComputeDerivativeGroup*NV capabilities to trim capabilities pass. (#5430)
+ - Do not crash when tryingto fold unsupported spec constant (#5496)
+ - instrument: Fix handling of gl_InvocationID (#5493)
+ - Fix nullptr argument in MarkInsertChain (#5465)
+ - opt: support 64-bit OpAccessChain index in FixStorageClass (#5446)
+ - opt: add StorageImageReadWithoutFormat to cap trim (#5475)
+ - opt: add PhysicalStorageBufferAddresses to trim (#5476)
+ - Fix array size calculation (#5463
+ - Validator
+ - spirv-val: Loosen restriction on base type of DebugTypePointer and DebugTypeQualifier (#5479)
+ - spirv-val: Add WorkgroupMemoryExplicitLayoutKHR check for Block (#5461)
+
+v2023.5 2023-10-15
+ - General
+ - Support 2 Intel extensions (#5357)
+ - SPV_QCOM_image_processing support (#5223)
+ - Optimizer
+ - opt: fix StorageInputOutput16 trimming. (#5359)
+ - opt: add StoragePushConstant16 to trim pass (#5366)
+ - opt: enable StorageUniform16 (#5371)
+ - opt: add bitmask support for capability trimming (#5372)
+ - opt: Add SwitchDescriptorSetPass (#5375)
+ - opt: add FragmentShader*InterlockEXT to capability trim pass (#5390)
+ - opt: add Int64 capability to trim pass (#5398)
+ - opt: add Float64 capability to trim pass (#5428)
+ - opt: add raytracing/rayquery to trim pass (#5397)
+ - opt: add ImageMSArray capability to trim pass. (#5395)
+ - Add SPV_KHR_physical_storage_buffer to allowlists (#5402)
+ - Add SPV_EXT_fragment_shader_interlock to allow lists (#5393)
+ - Make sure that fragment shader interlock instructions are not removed by DCE (#5400)
+ - instrument: Use Import linkage for instrumentation functions (#5355)
+ - Add a new legalization pass to dedupe invocation interlock instructions (#5409)
+ - instrument: Ensure linking works even of nothing is changed (#5419)
+ - Validator
+ - Move token version/cap/ext checks from parsing to validation (#5370)
+ - val: re-add ImageMSArray validation (#5394)
+ - Linker
+ - linker: Add --use-highest-version option
+
+v2023.4 2023-07-17
+ - General
+ - Set cmake_policy CMP0128 (#5341)
+ - Add python3 requirement for the script (#5326)
+ - Add support for LiteralFloat type (#5323)
+ - SPV_KHR_cooperative_matrix (#5286)
+ - Allow OpTypeBool in UniformConstant (#5237)
+ - Allow physical storage buffer pointer in IO (#5251)
+ - Remove const zero image operands (#5232)
+ - Optimizer
+ - Enable vector constant folding (#4913) (#5272)
+ - Fold negation of integer vectors (#5269)
+ - Add folding rule for OpTranspose (#5241)
+ - Add SPV_NV_bindless_texture to spirv optimizations (#5231)
+ - Fix incorrect half float conversion (#5349)
+ - Add SPV_EXT_shader_atomic_float_add to allow lists (#5348)
+ - Instrument
+ - instrument: Cast gl_VertexIndex and InstanceIndex to uint (#5319)
+ - instrument: Fix buffer address length calculations (#5257)
+ - instrument: Reduce number of inst_bindless_stream_write_6 calls (#5327)
+ - Validator
+ - Validate GroupNonUniform instructions (#5296)
+ - spirv-val: Label SPV_KHR_cooperative_matrix VUID (#5301)
+ - Validate layouts for PhysicalStorageBuffer pointers (#5291)
+ - spirv-val: Remove VUID from 1.3.251 spec (#5244)
+ - Diff
+ - spirv-diff: Update test expectations (#5264)
+ - spirv-diff: Leave undefined ids unpaired. (#5262)
+ - spirv-diff: Properly match SPV_KHR_ray_query types. (#5259)
+ - diff: Don't give up entry point matching too early. (#5224)
+
+v2023.3 2023-05-15
+ - General
+ - Update spirv_headers to include SPV_KHR_ray_tracing_position_fetch (#5205)
+ - spirv-tools: Add support for QNX (#5211)
+ - build: set std=c++17 for BUILD.gn (#5162)
+ - Optimizer
+ - Run ADCE when the printf extension is used. (#5215)
+ - Don't convert struct members to half (#5201)
+ - Apply scalar replacement on vars with Pointer decorations (#5208)
+ - opt: Fix null deref in OpMatrixTimesVector and OpVectorTimesMatrix (#5199)
+ - instrument: Add set and binding to bindless error records (#5204)
+ - instrument: Change descriptor state storage format (#5178)
+ - Fix LICMPass (#5087)
+ - Add Vulkan memory model to allow lists (#5173)
+ - Do not remove control barrier after spv1.3 (#5174)
+ - Validator
+ - spirv-val: Label Interface Location/Component VUIDs (#5221)
+ - Add support for SPV_EXT_shader_tile_image (#5188)
+ - Fix vector OpConstantComposite type validation (#5191)
+ - spirv-val: Label new Vulkan VUID 07951 (#5154)
+ - Fuzz
+ - Do not define GOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE if it is already defined. (#5200)
+
v2023.2 2023-03-10
- General
- build: move from c++11 to c++17 (#4983)
diff --git a/third_party/SPIRV-Tools/CMakeLists.txt b/third_party/SPIRV-Tools/CMakeLists.txt
index 71cdc00c4..0ba173f1d 100644
--- a/third_party/SPIRV-Tools/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/CMakeLists.txt
@@ -16,6 +16,16 @@ cmake_minimum_required(VERSION 3.17.2)
project(spirv-tools)
+# Avoid a bug in CMake 3.22.1. By default it will set -std=c++11 for
+# targets in test/*, when those tests need -std=c++17.
+# https://github.com/KhronosGroup/SPIRV-Tools/issues/5340
+# The bug is fixed in CMake 3.22.2
+if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.22.1")
+ if (${CMAKE_VERSION} VERSION_LESS "3.22.2")
+ cmake_policy(SET CMP0128 NEW)
+ endif()
+endif()
+
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
enable_testing()
@@ -53,6 +63,8 @@ elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS")
add_definitions(-DSPIRV_IOS)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "tvOS")
add_definitions(-DSPIRV_TVOS)
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "visionOS")
+ add_definitions(-DSPIRV_VISIONOS)
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Android")
add_definitions(-DSPIRV_ANDROID)
set(SPIRV_TIMER_ENABLED ${SPIRV_ALLOW_TIMERS})
@@ -231,7 +243,7 @@ function(spvtools_default_compile_options TARGET)
# For MinGW cross compile, statically link to the C++ runtime.
# But it still depends on MSVCRT.dll.
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
- if (${CMAKE_CXX_COMPILER_ID} MATCHES "GNU")
+ if (NOT MSVC)
set_target_properties(${TARGET} PROPERTIES
LINK_FLAGS -static -static-libgcc -static-libstdc++)
endif()
@@ -250,7 +262,7 @@ if(NOT COMMAND find_host_program)
endif()
# Tests require Python3
-find_host_package(PythonInterp 3 REQUIRED)
+find_host_package(Python3 REQUIRED)
# Check for symbol exports on Linux.
# At the moment, this check will fail on the OSX build machines for the Android NDK.
@@ -259,7 +271,7 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
macro(spvtools_check_symbol_exports TARGET)
if (NOT "${SPIRV_SKIP_TESTS}")
add_test(NAME spirv-tools-symbol-exports-${TARGET}
- COMMAND ${PYTHON_EXECUTABLE}
+ COMMAND Python3::Interpreter
${spirv-tools_SOURCE_DIR}/utils/check_symbol_exports.py "$<TARGET_FILE:${TARGET}>")
endif()
endmacro()
@@ -292,15 +304,23 @@ if(ENABLE_SPIRV_TOOLS_INSTALL)
endmacro()
endif()
-# Defaults to OFF if the user didn't set it.
-option(SPIRV_SKIP_EXECUTABLES
- "Skip building the executable and tests along with the library"
- ${SPIRV_SKIP_EXECUTABLES})
-option(SPIRV_SKIP_TESTS
- "Skip building tests along with the library" ${SPIRV_SKIP_TESTS})
-if ("${SPIRV_SKIP_EXECUTABLES}")
+# Currently iOS and Android are very similar.
+# They both have their own packaging (APP/APK).
+# Which makes regular executables/testing problematic.
+#
+# Currently the only deliverables for these platforms are
+# libraries (either STATIC or SHARED).
+#
+# Furthermore testing is equally problematic.
+if (IOS OR ANDROID)
+ set(SPIRV_SKIP_EXECUTABLES ON)
+endif()
+
+option(SPIRV_SKIP_EXECUTABLES "Skip building the executable and tests along with the library")
+if (SPIRV_SKIP_EXECUTABLES)
set(SPIRV_SKIP_TESTS ON)
endif()
+option(SPIRV_SKIP_TESTS "Skip building tests along with the library")
# Defaults to ON. The checks can be time consuming.
# Turn off if they take too long.
@@ -358,7 +378,7 @@ endif(ENABLE_SPIRV_TOOLS_INSTALL)
if (NOT "${SPIRV_SKIP_TESTS}")
add_test(NAME spirv-tools-copyrights
- COMMAND ${PYTHON_EXECUTABLE} utils/check_copyright.py
+ COMMAND Python3::Interpreter utils/check_copyright.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
endif()
@@ -367,7 +387,8 @@ set(SPIRV_SHARED_LIBRARIES "-lSPIRV-Tools-shared")
# Build pkg-config file
# Use a first-class target so it's regenerated when relevant files are updated.
-add_custom_target(spirv-tools-pkg-config ALL
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc
COMMAND ${CMAKE_COMMAND}
-DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
-DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in
@@ -377,8 +398,9 @@ add_custom_target(spirv-tools-pkg-config ALL
-DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
-DSPIRV_LIBRARIES=${SPIRV_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
- DEPENDS "CHANGES" "cmake/SPIRV-Tools.pc.in" "cmake/write_pkg_config.cmake")
-add_custom_target(spirv-tools-shared-pkg-config ALL
+ DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc
COMMAND ${CMAKE_COMMAND}
-DCHANGES_FILE=${CMAKE_CURRENT_SOURCE_DIR}/CHANGES
-DTEMPLATE_FILE=${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in
@@ -388,7 +410,10 @@ add_custom_target(spirv-tools-shared-pkg-config ALL
-DCMAKE_INSTALL_INCLUDEDIR=${CMAKE_INSTALL_INCLUDEDIR}
-DSPIRV_SHARED_LIBRARIES=${SPIRV_SHARED_LIBRARIES}
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake
- DEPENDS "CHANGES" "cmake/SPIRV-Tools-shared.pc.in" "cmake/write_pkg_config.cmake")
+ DEPENDS "CHANGES" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/SPIRV-Tools-shared.pc.in" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/write_pkg_config.cmake")
+add_custom_target(spirv-tools-pkg-config
+ ALL
+ DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools-shared.pc ${CMAKE_CURRENT_BINARY_DIR}/SPIRV-Tools.pc)
# Install pkg-config file
if (ENABLE_SPIRV_TOOLS_INSTALL)
diff --git a/third_party/SPIRV-Tools/CONTRIBUTING.md b/third_party/SPIRV-Tools/CONTRIBUTING.md
index 893998e1b..11fb4e2c7 100644
--- a/third_party/SPIRV-Tools/CONTRIBUTING.md
+++ b/third_party/SPIRV-Tools/CONTRIBUTING.md
@@ -3,7 +3,7 @@
## For users: Reporting bugs and requesting features
We organize known future work in GitHub projects. See
-[Tracking SPIRV-Tools work with GitHub projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/docs/projects.md)
+[Tracking SPIRV-Tools work with GitHub projects](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/docs/projects.md)
for more.
To report a new bug or request a new feature, please file a GitHub issue. Please
@@ -46,7 +46,7 @@ sign the CLA until after you've submitted your code for review and a member has
approved it, but you must do it before we can put your code into our codebase.
See
-[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/master/README.md)
+[README.md](https://github.com/KhronosGroup/SPIRV-Tools/blob/main/README.md)
for instruction on how to get, build, and test the source. Once you have made
your changes:
@@ -59,7 +59,7 @@ your changes:
* If your patch completely fixes bug 1234, the commit message should say
`Fixes https://github.com/KhronosGroup/SPIRV-Tools/issues/1234` When you do
this, the issue will be closed automatically when the commit goes into
- master. Also, this helps us update the [CHANGES](CHANGES) file.
+ main. Also, this helps us update the [CHANGES](CHANGES) file.
* Watch the continuous builds to make sure they pass.
* Request a code review.
@@ -107,7 +107,7 @@ should pay particular attention to:
## For maintainers: Merging a PR
-We intend to maintain a linear history on the GitHub master branch, and the
+We intend to maintain a linear history on the GitHub main branch, and the
build and its tests should pass at each commit in that history. A linear
always-working history is easier to understand and to bisect in case we want to
find which commit introduced a bug. The
diff --git a/third_party/SPIRV-Tools/DEPS b/third_party/SPIRV-Tools/DEPS
index 9b6039e89..8413d1beb 100644
--- a/third_party/SPIRV-Tools/DEPS
+++ b/third_party/SPIRV-Tools/DEPS
@@ -3,18 +3,23 @@ use_relative_paths = True
vars = {
'github': 'https://github.com',
- 'effcee_revision': '66edefd2bb641de8a2f46b476de21f227fc03a28',
+ 'abseil_revision': '79ca5d7aad63973c83a4962a66ab07cd623131ea',
- 'googletest_revision': 'bc860af08783b8113005ca7697da5f5d49a8056f',
+ 'effcee_revision': '19b4aa87af25cb4ee779a071409732f34bfc305c',
+
+ 'googletest_revision': '5a37b517ad4ab6738556f0284c256cae1466c5b4',
# Use protobufs before they gained the dependency on abseil
'protobuf_revision': 'v21.12',
- 're2_revision': 'c9cba76063cf4235c1a15dd14a24a4ef8d623761',
- 'spirv_headers_revision': '268a061764ee69f09a477a695bf6a11ffe311b8d',
+ 're2_revision': '917047f3606d3ba9e2de0d383c3cd80c94ed732c',
+ 'spirv_headers_revision': '4f7b471f1a66b6d06462cd4ba57628cc0cd087d7',
}
deps = {
+ 'external/abseil_cpp':
+ Var('github') + '/abseil/abseil-cpp.git@' + Var('abseil_revision'),
+
'external/effcee':
Var('github') + '/google/effcee.git@' + Var('effcee_revision'),
diff --git a/third_party/SPIRV-Tools/MODULE.bazel b/third_party/SPIRV-Tools/MODULE.bazel
new file mode 100644
index 000000000..c36fe456f
--- /dev/null
+++ b/third_party/SPIRV-Tools/MODULE.bazel
@@ -0,0 +1,7 @@
+bazel_dep(name = "bazel_skylib", version = "1.5.0")
+
+bazel_dep(name = "googletest", dev_dependency = True)
+local_path_override(
+ module_name = "googletest",
+ path = "external/googletest",
+)
diff --git a/third_party/SPIRV-Tools/README.md b/third_party/SPIRV-Tools/README.md
index 92e4d3c06..7db5bd42a 100644
--- a/third_party/SPIRV-Tools/README.md
+++ b/third_party/SPIRV-Tools/README.md
@@ -1,4 +1,5 @@
# SPIR-V Tools
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/KhronosGroup/SPIRV-Tools/badge)](https://securityscorecards.dev/viewer/?uri=github.com/KhronosGroup/SPIRV-Tools)
NEWS 2023-01-11: Development occurs on the `main` branch.
@@ -23,6 +24,13 @@ headers, and XML registry.
## Downloads
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
+
+For convenience, here are also links to the latest builds (HEAD).
+Those are untested automated builds. Those are not official releases, nor
+are guaranteed to work. Official releases builds are in the Vulkan SDK.
+
<img alt="Linux" src="kokoro/img/linux.png" width="20px" height="20px" hspace="2px"/>[![Linux Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_linux_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_release.html)
<img alt="MacOS" src="kokoro/img/macos.png" width="20px" height="20px" hspace="2px"/>[![MacOS Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_macos_clang_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_release.html)
<img alt="Windows" src="kokoro/img/windows.png" width="20px" height="20px" hspace="2px"/>[![Windows Build Status](https://storage.googleapis.com/spirv-tools/badges/build_status_windows_release.svg)](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2019_release.html)
@@ -48,17 +56,14 @@ version. An API call reports the software version as a C-style string.
## Releases
-Some versions of SPIRV-Tools are tagged as stable releases (see
-[tags](https://github.com/KhronosGroup/SPIRV-Tools/tags) on github).
-These versions undergo extra testing.
-Releases are not directly related to releases (or versions) of
-[SPIRV-Headers][spirv-headers].
-Releases of SPIRV-Tools are tested against the version of SPIRV-Headers listed
-in the [DEPS](DEPS) file.
-The release generally uses the most recent compatible version of SPIRV-Headers
-available at the time of release.
-No version of SPIRV-Headers other than the one listed in the DEPS file is
-guaranteed to work with the SPIRV-Tools release.
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
+
+You can find either the prebuilt, and QA tested binaries, or download the
+SDK Config, which lists the commits to use to build the release from scratch.
+
+GitHub releases are deprecated, and we will not publish new releases until
+further notice.
## Supported features
@@ -292,16 +297,18 @@ For some kinds of development, you may need the latest sources from the third-pa
git clone https://github.com/google/googletest.git spirv-tools/external/googletest
git clone https://github.com/google/effcee.git spirv-tools/external/effcee
git clone https://github.com/google/re2.git spirv-tools/external/re2
+ git clone https://github.com/abseil/abseil-cpp.git spirv-tools/external/abseil_cpp
#### Dependency on Effcee
Some tests depend on the [Effcee][effcee] library for stateful matching.
-Effcee itself depends on [RE2][re2].
+Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp].
* If SPIRV-Tools is configured as part of a larger project that already uses
Effcee, then that project should include Effcee before SPIRV-Tools.
-* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`
- and RE2 sources to appear in `external/re2`.
+* Otherwise, SPIRV-Tools expects Effcee sources to appear in `external/effcee`,
+ RE2 sources to appear in `external/re2`, and Abseil sources to appear in
+ `external/abseil_cpp`.
### Source code organization
@@ -313,6 +320,9 @@ Effcee itself depends on [RE2][re2].
* `external/re2`: Location of [RE2][re2] sources, if the `re2` library is not already
configured by an enclosing project.
(The Effcee project already requires RE2.)
+* `external/abseil_cpp`: Location of [Abseil][abseil-cpp] sources, if Abseil is
+ not already configured by an enclosing project.
+ (The RE2 project already requires Abseil.)
* `include/`: API clients should add this directory to the include search path
* `external/spirv-headers`: Intended location for
[SPIR-V headers][spirv-headers], not provided
@@ -381,15 +391,8 @@ fuzzer tests.
### Build using Bazel
You can also use [Bazel](https://bazel.build/) to build the project.
-On linux:
-```sh
-cd <spirv-dir>
-bazel build --cxxopt=-std=c++17 :all
-```
-
-On windows:
```sh
-bazel build --cxxopt=/std:c++17 :all
+bazel build :all
```
### Build a node.js package using Emscripten
@@ -427,7 +430,7 @@ targets, you need to install CMake Version 2.8.12 or later.
- [Python 3](http://www.python.org/): for utility scripts and running the test
suite.
- [Bazel](https://bazel.build/) (optional): if building the source with Bazel,
-you need to install Bazel Version 5.0.0 on your machine. Other versions may
+you need to install Bazel Version 7.0.2 on your machine. Other versions may
also work, but are not verified.
- [Emscripten SDK](https://emscripten.org) (optional): if building the
WebAssembly module.
@@ -480,12 +483,12 @@ iterator debugging.
### Android ndk-build
SPIR-V Tools supports building static libraries `libSPIRV-Tools.a` and
-`libSPIRV-Tools-opt.a` for Android:
+`libSPIRV-Tools-opt.a` for Android. Using the Android NDK r25c or later:
```
cd <spirv-dir>
-export ANDROID_NDK=/path/to/your/ndk
+export ANDROID_NDK=/path/to/your/ndk # NDK r25c or later
mkdir build && cd build
mkdir libs
@@ -798,6 +801,7 @@ limitations under the License.
[googletest-issue-610]: https://github.com/google/googletest/issues/610
[effcee]: https://github.com/google/effcee
[re2]: https://github.com/google/re2
+[abseil-cpp]: https://github.com/abseil/abseil-cpp
[CMake]: https://cmake.org/
[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
diff --git a/third_party/SPIRV-Tools/SECURITY.md b/third_party/SPIRV-Tools/SECURITY.md
new file mode 100644
index 000000000..99c5f441a
--- /dev/null
+++ b/third_party/SPIRV-Tools/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+## Supported Versions
+
+Security updates are applied only to the latest release.
+
+## Reporting a Vulnerability
+
+If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
+
+Please disclose it at [security advisory](https://github.com/KhronosGroup/SPIRV-Tools/security/advisories/new).
+
+This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
diff --git a/third_party/SPIRV-Tools/WORKSPACE b/third_party/SPIRV-Tools/WORKSPACE
index 5abfc98bc..6e780594c 100644
--- a/third_party/SPIRV-Tools/WORKSPACE
+++ b/third_party/SPIRV-Tools/WORKSPACE
@@ -4,11 +4,6 @@ local_repository(
)
local_repository(
- name = "com_google_googletest",
- path = "external/googletest",
-)
-
-local_repository(
name = "com_googlesource_code_re2",
path = "external/re2",
)
@@ -17,3 +12,8 @@ local_repository(
name = "com_google_effcee",
path = "external/effcee",
)
+
+local_repository(
+ name = "abseil-cpp",
+ path = "external/abseil_cpp",
+)
diff --git a/third_party/SPIRV-Tools/build_defs.bzl b/third_party/SPIRV-Tools/build_defs.bzl
index 4d6f15cb2..76bf3e792 100644
--- a/third_party/SPIRV-Tools/build_defs.bzl
+++ b/third_party/SPIRV-Tools/build_defs.bzl
@@ -88,7 +88,7 @@ def generate_core_tables(version):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_grammar_tables"],
+ tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -123,7 +123,7 @@ def generate_enum_string_mapping(version):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_grammar_tables"],
+ tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -151,7 +151,7 @@ def generate_opencl_tables(version):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_grammar_tables"],
+ tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -179,7 +179,7 @@ def generate_glsl_tables(version):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_grammar_tables"],
+ tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -207,7 +207,7 @@ def generate_vendor_tables(extension, operand_kind_prefix = ""):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_grammar_tables"],
+ tools = [":generate_grammar_tables"],
visibility = ["//visibility:private"],
)
@@ -229,6 +229,6 @@ def generate_extinst_lang_headers(name, grammar = None):
outs = outs.values(),
cmd = cmd,
cmd_bat = cmd,
- exec_tools = [":generate_language_headers"],
+ tools = [":generate_language_headers"],
visibility = ["//visibility:private"],
)
diff --git a/third_party/SPIRV-Tools/docs/downloads.md b/third_party/SPIRV-Tools/docs/downloads.md
index 168937a70..0454b9ea6 100644
--- a/third_party/SPIRV-Tools/docs/downloads.md
+++ b/third_party/SPIRV-Tools/docs/downloads.md
@@ -1,8 +1,24 @@
# Downloads
-## Latest builds
+## Vulkan SDK
+
+The official releases for SPIRV-Tools can be found on LunarG's
+[SDK download page](https://vulkan.lunarg.com/sdk/home).
+The Vulkan SDK is updated approximately every six weeks.
+
+## Android NDK
+
+SPIRV-Tools host executables, and library sources are published as
+part of the [Android NDK](https://developer.android.com/ndk/downloads).
+
+## Automated builds
+
+For convenience, here are also links to the latest builds (HEAD).
+Those are untested automated builds. Those are not official releases, nor
+are guaranteed to work. Official releases builds are in the Android NDK or
+Vulkan SDK.
-Download the latest builds of the [master](https://github.com/KhronosGroup/SPIRV-Tools/tree/master) branch.
+Download the latest builds of the [main](https://github.com/KhronosGroup/SPIRV-Tools/tree/main) branch.
### Release build
| Windows | Linux | MacOS |
@@ -15,14 +31,3 @@ Download the latest builds of the [master](https://github.com/KhronosGroup/SPIRV
| --- | --- | --- |
| [MSVC 2017](https://storage.googleapis.com/spirv-tools/badges/build_link_windows_vs2017_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_clang_debug.html) | [clang](https://storage.googleapis.com/spirv-tools/badges/build_link_macos_clang_debug.html) |
| | [gcc](https://storage.googleapis.com/spirv-tools/badges/build_link_linux_gcc_debug.html) | |
-
-
-## Vulkan SDK
-
-SPIRV-Tools is published as part of the [LunarG Vulkan SDK](https://www.lunarg.com/vulkan-sdk/).
-The Vulkan SDK is updated approximately every six weeks.
-
-## Android NDK
-
-SPIRV-Tools host executables, and library sources are published as
-part of the [Android NDK](https://developer.android.com/ndk/downloads).
diff --git a/third_party/SPIRV-Tools/docs/projects.md b/third_party/SPIRV-Tools/docs/projects.md
index 8f7f0bcd9..cc88cb3ff 100644
--- a/third_party/SPIRV-Tools/docs/projects.md
+++ b/third_party/SPIRV-Tools/docs/projects.md
@@ -34,7 +34,7 @@ through the project workflow:
ones.
* They determine if the work for a card has been completed.
* Normally they are the person (or persons) who can approve and merge a pull
- request into the `master` branch.
+ request into the `main` branch.
Our projects organize cards into the following columns:
* `Ideas`: Work which could be done, captured either as Cards or Notes.
@@ -51,7 +51,7 @@ Our projects organize cards into the following columns:
claimed by someone.
* `Done`: Issues which have been resolved, by completing their work.
* The changes have been applied to the repository, typically by being pushed
- into the `master` branch.
+ into the `main` branch.
* Other kinds of work could update repository settings, for example.
* `Rejected ideas`: Work which has been considered, but which we don't want
implemented.
diff --git a/third_party/SPIRV-Tools/external/CMakeLists.txt b/third_party/SPIRV-Tools/external/CMakeLists.txt
index 6ee37d9ea..5d8a3dab0 100644
--- a/third_party/SPIRV-Tools/external/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/external/CMakeLists.txt
@@ -41,8 +41,6 @@ if (IS_DIRECTORY ${SPIRV_HEADER_DIR})
# Do this so enclosing projects can use SPIRV-Headers_SOURCE_DIR to find
# headers to include.
if (NOT DEFINED SPIRV-Headers_SOURCE_DIR)
- set(SPIRV_HEADERS_SKIP_INSTALL ON)
- set(SPIRV_HEADERS_SKIP_EXAMPLES ON)
add_subdirectory(${SPIRV_HEADER_DIR})
endif()
else()
@@ -93,10 +91,22 @@ if (NOT ${SPIRV_SKIP_TESTS})
# Find Effcee and RE2, for testing.
+ # RE2 depends on Abseil. We set absl_SOURCE_DIR if it is not already set, so
+ # that effcee can find abseil.
+ if(NOT TARGET absl::base)
+ if (NOT absl_SOURCE_DIR)
+ if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp)
+ set(absl_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/abseil_cpp" CACHE STRING "Abseil source dir" )
+ endif()
+ endif()
+ endif()
+
# First find RE2, since Effcee depends on it.
# If already configured, then use that. Otherwise, prefer to find it under 're2'
# in this directory.
if (NOT TARGET re2)
+
+
# If we are configuring RE2, then turn off its testing. It takes a long time and
# does not add much value for us. If an enclosing project configured RE2, then it
# has already chosen whether to enable RE2 testing.
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/instrument.hpp b/third_party/SPIRV-Tools/include/spirv-tools/instrument.hpp
index 448cf8ab7..0a6e6306e 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/instrument.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/instrument.hpp
@@ -73,213 +73,14 @@ static const int kInstCommonOutShaderId = 1;
// which generated the validation error.
static const int kInstCommonOutInstructionIdx = 2;
-// This is the stage which generated the validation error. This word is used
-// to determine the contents of the next two words in the record.
-// 0:Vert, 1:TessCtrl, 2:TessEval, 3:Geom, 4:Frag, 5:Compute
-static const int kInstCommonOutStageIdx = 3;
-static const int kInstCommonOutCnt = 4;
-
-// Stage-specific Stream Record Offsets
-//
-// Each stage will contain different values in the next set of words of the
-// record used to identify which instantiation of the shader generated the
-// validation error.
-//
-// Vertex Shader Output Record Offsets
-static const int kInstVertOutVertexIndex = kInstCommonOutCnt;
-static const int kInstVertOutInstanceIndex = kInstCommonOutCnt + 1;
-static const int kInstVertOutUnused = kInstCommonOutCnt + 2;
-
-// Frag Shader Output Record Offsets
-static const int kInstFragOutFragCoordX = kInstCommonOutCnt;
-static const int kInstFragOutFragCoordY = kInstCommonOutCnt + 1;
-static const int kInstFragOutUnused = kInstCommonOutCnt + 2;
-
-// Compute Shader Output Record Offsets
-static const int kInstCompOutGlobalInvocationIdX = kInstCommonOutCnt;
-static const int kInstCompOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
-static const int kInstCompOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
-
-// Tessellation Control Shader Output Record Offsets
-static const int kInstTessCtlOutInvocationId = kInstCommonOutCnt;
-static const int kInstTessCtlOutPrimitiveId = kInstCommonOutCnt + 1;
-static const int kInstTessCtlOutUnused = kInstCommonOutCnt + 2;
-
-// Tessellation Eval Shader Output Record Offsets
-static const int kInstTessEvalOutPrimitiveId = kInstCommonOutCnt;
-static const int kInstTessEvalOutTessCoordU = kInstCommonOutCnt + 1;
-static const int kInstTessEvalOutTessCoordV = kInstCommonOutCnt + 2;
-
-// Geometry Shader Output Record Offsets
-static const int kInstGeomOutPrimitiveId = kInstCommonOutCnt;
-static const int kInstGeomOutInvocationId = kInstCommonOutCnt + 1;
-static const int kInstGeomOutUnused = kInstCommonOutCnt + 2;
-
-// Ray Tracing Shader Output Record Offsets
-static const int kInstRayTracingOutLaunchIdX = kInstCommonOutCnt;
-static const int kInstRayTracingOutLaunchIdY = kInstCommonOutCnt + 1;
-static const int kInstRayTracingOutLaunchIdZ = kInstCommonOutCnt + 2;
-
-// Mesh Shader Output Record Offsets
-static const int kInstMeshOutGlobalInvocationIdX = kInstCommonOutCnt;
-static const int kInstMeshOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
-static const int kInstMeshOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
-
-// Task Shader Output Record Offsets
-static const int kInstTaskOutGlobalInvocationIdX = kInstCommonOutCnt;
-static const int kInstTaskOutGlobalInvocationIdY = kInstCommonOutCnt + 1;
-static const int kInstTaskOutGlobalInvocationIdZ = kInstCommonOutCnt + 2;
-
-// Size of Common and Stage-specific Members
-static const int kInstStageOutCnt = kInstCommonOutCnt + 3;
-
-// Validation Error Code Offset
-//
-// This identifies the validation error. It also helps to identify
-// how many words follow in the record and their meaning.
-static const int kInstValidationOutError = kInstStageOutCnt;
-
-// Validation-specific Output Record Offsets
-//
-// Each different validation will generate a potentially different
-// number of words at the end of the record giving more specifics
-// about the validation error.
-//
-// A bindless bounds error will output the index and the bound.
-static const int kInstBindlessBoundsOutDescSet = kInstStageOutCnt + 1;
-static const int kInstBindlessBoundsOutDescBinding = kInstStageOutCnt + 2;
-static const int kInstBindlessBoundsOutDescIndex = kInstStageOutCnt + 3;
-static const int kInstBindlessBoundsOutDescBound = kInstStageOutCnt + 4;
-static const int kInstBindlessBoundsOutUnused = kInstStageOutCnt + 5;
-static const int kInstBindlessBoundsOutCnt = kInstStageOutCnt + 6;
-
-// A descriptor uninitialized error will output the index.
-static const int kInstBindlessUninitOutDescSet = kInstStageOutCnt + 1;
-static const int kInstBindlessUninitOutBinding = kInstStageOutCnt + 2;
-static const int kInstBindlessUninitOutDescIndex = kInstStageOutCnt + 3;
-static const int kInstBindlessUninitOutUnused = kInstStageOutCnt + 4;
-static const int kInstBindlessUninitOutUnused2 = kInstStageOutCnt + 5;
-static const int kInstBindlessUninitOutCnt = kInstStageOutCnt + 6;
-
-// A buffer out-of-bounds error will output the descriptor
-// index, the buffer offset and the buffer size
-static const int kInstBindlessBuffOOBOutDescSet = kInstStageOutCnt + 1;
-static const int kInstBindlessBuffOOBOutDescBinding = kInstStageOutCnt + 2;
-static const int kInstBindlessBuffOOBOutDescIndex = kInstStageOutCnt + 3;
-static const int kInstBindlessBuffOOBOutBuffOff = kInstStageOutCnt + 4;
-static const int kInstBindlessBuffOOBOutBuffSize = kInstStageOutCnt + 5;
-static const int kInstBindlessBuffOOBOutCnt = kInstStageOutCnt + 6;
-
-// A buffer address unalloc error will output the 64-bit pointer in
-// two 32-bit pieces, lower bits first.
-static const int kInstBuffAddrUnallocOutDescPtrLo = kInstStageOutCnt + 1;
-static const int kInstBuffAddrUnallocOutDescPtrHi = kInstStageOutCnt + 2;
-static const int kInstBuffAddrUnallocOutCnt = kInstStageOutCnt + 3;
-
-// Maximum Output Record Member Count
-static const int kInstMaxOutCnt = kInstStageOutCnt + 6;
-
-// Validation Error Codes
-//
-// These are the possible validation error codes.
-static const int kInstErrorBindlessBounds = 0;
-static const int kInstErrorBindlessUninit = 1;
-static const int kInstErrorBuffAddrUnallocRef = 2;
-// Deleted: static const int kInstErrorBindlessBuffOOB = 3;
-// This comment will will remain for 2 releases to allow
-// for the transition of all builds. Buffer OOB is
-// generating the following four differentiated codes instead:
-static const int kInstErrorBuffOOBUniform = 4;
-static const int kInstErrorBuffOOBStorage = 5;
-static const int kInstErrorBuffOOBUniformTexel = 6;
-static const int kInstErrorBuffOOBStorageTexel = 7;
-static const int kInstErrorMax = kInstErrorBuffOOBStorageTexel;
-
-// Direct Input Buffer Offsets
-//
-// The following values provide member offsets into the input buffers
-// consumed by InstrumentPass::GenDebugDirectRead(). This method is utilized
-// by InstBindlessCheckPass.
-//
-// The only object in an input buffer is a runtime array of unsigned
-// integers. Each validation will have its own formatting of this array.
-static const int kDebugInputDataOffset = 0;
-
// Debug Buffer Bindings
//
// These are the bindings for the different buffers which are
// read or written by the instrumentation passes.
//
-// This is the output buffer written by InstBindlessCheckPass,
-// InstBuffAddrCheckPass, and possibly other future validations.
-static const int kDebugOutputBindingStream = 0;
-
-// The binding for the input buffer read by InstBindlessCheckPass.
-static const int kDebugInputBindingBindless = 1;
-
-// The binding for the input buffer read by InstBuffAddrCheckPass.
-static const int kDebugInputBindingBuffAddr = 2;
-
// This is the output buffer written by InstDebugPrintfPass.
static const int kDebugOutputPrintfStream = 3;
-// clang-format off
-// Bindless Validation Input Buffer Format
-//
-// An input buffer for bindless validation has this structure:
-// GLSL:
-// layout(buffer_reference, std430, buffer_reference_align = 8) buffer DescriptorSetData {
-// uint num_bindings;
-// uint data[];
-// };
-//
-// layout(set = 7, binding = 1, std430) buffer inst_bindless_InputBuffer
-// {
-// DescriptorSetData desc_sets[32];
-// } inst_bindless_input_buffer;
-//
-//
-// To look up the length of a binding:
-// uint length = inst_bindless_input_buffer[set].data[binding];
-// Scalar bindings have a length of 1.
-//
-// To look up the initialization state of a descriptor in a binding:
-// uint num_bindings = inst_bindless_input_buffer[set].num_bindings;
-// uint binding_state_start = inst_bindless_input_buffer[set].data[num_bindings + binding];
-// uint init_state = inst_bindless_input_buffer[set].data[binding_state_start + index];
-//
-// For scalar bindings, use 0 for the index.
-// clang-format on
-//
-// The size of the inst_bindless_input_buffer array, regardless of how many
-// descriptor sets the device supports.
-static const int kDebugInputBindlessMaxDescSets = 32;
-
-// Buffer Device Address Input Buffer Format
-//
-// An input buffer for buffer device address validation consists of a single
-// array of unsigned 64-bit integers we will call Data[]. This array is
-// formatted as follows:
-//
-// At offset kDebugInputBuffAddrPtrOffset is a list of sorted valid buffer
-// addresses. The list is terminated with the address 0xffffffffffffffff.
-// If 0x0 is not a valid buffer address, this address is inserted at the
-// start of the list.
-//
-static const int kDebugInputBuffAddrPtrOffset = 1;
-//
-// At offset kDebugInputBuffAddrLengthOffset in Data[] is a single uint64 which
-// gives an offset to the start of the buffer length data. More
-// specifically, for a buffer whose pointer is located at input buffer offset
-// i, the length is located at:
-//
-// Data[ i - kDebugInputBuffAddrPtrOffset
-// + Data[ kDebugInputBuffAddrLengthOffset ] ]
-//
-// The length associated with the 0xffffffffffffffff address is zero. If
-// not a valid buffer, the length associated with the 0x0 address is zero.
-static const int kDebugInputBuffAddrLengthOffset = 0;
-
} // namespace spvtools
#endif // INCLUDE_SPIRV_TOOLS_INSTRUMENT_HPP_
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
index 542b74532..83b1a8e9b 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
+++ b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.h
@@ -33,15 +33,19 @@ extern "C" {
#else
#define SPIRV_TOOLS_EXPORT __declspec(dllimport)
#endif
+#define SPIRV_TOOLS_LOCAL
#else
#if defined(SPIRV_TOOLS_IMPLEMENTATION)
#define SPIRV_TOOLS_EXPORT __attribute__((visibility("default")))
+#define SPIRV_TOOLS_LOCAL __attribute__((visibility("hidden")))
#else
#define SPIRV_TOOLS_EXPORT
+#define SPIRV_TOOLS_LOCAL
#endif
#endif
#else
#define SPIRV_TOOLS_EXPORT
+#define SPIRV_TOOLS_LOCAL
#endif
// Helpers
@@ -143,6 +147,7 @@ typedef enum spv_operand_type_t {
// may be larger than 32, which would require such a typed literal value to
// occupy multiple SPIR-V words.
SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER,
+ SPV_OPERAND_TYPE_LITERAL_FLOAT, // Always 32-bit float.
// Set 3: The literal string operand type.
SPV_OPERAND_TYPE_LITERAL_STRING,
@@ -285,6 +290,28 @@ typedef enum spv_operand_type_t {
// An optional packed vector format
SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT,
+ // Concrete operand types for cooperative matrix.
+ SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS,
+ // An optional cooperative matrix operands
+ SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS,
+ SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT,
+ SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE,
+
+ // Enum type from SPV_INTEL_global_variable_fpga_decorations
+ SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER,
+ // Enum type from SPV_INTEL_global_variable_host_access
+ SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER,
+ // Enum type from SPV_INTEL_cache_controls
+ SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL,
+ // Enum type from SPV_INTEL_cache_controls
+ SPV_OPERAND_TYPE_STORE_CACHE_CONTROL,
+ // Enum type from SPV_INTEL_maximum_registers
+ SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS,
+ // Enum type from SPV_NV_raw_access_chains
+ SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS,
+ // Optional enum type from SPV_NV_raw_access_chains
+ SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS,
+
// This is a sentinel value, and does not represent an operand type.
// It should come last.
SPV_OPERAND_TYPE_NUM_OPERAND_TYPES,
@@ -310,6 +337,7 @@ typedef enum spv_ext_inst_type_t {
SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100,
+ SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION,
// Multiple distinct extended instruction set types could return this
// value, if they are prefixed with NonSemantic. and are otherwise
@@ -949,9 +977,16 @@ SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag(
spv_optimizer_t* optimizer, const char* flag);
// Registers passes specified by length number of flags in an optimizer object.
+// Passes may remove interface variables that are unused.
SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags(
spv_optimizer_t* optimizer, const char** flags, const size_t flag_count);
+// Registers passes specified by length number of flags in an optimizer object.
+// Passes will not remove interface variables.
+SPIRV_TOOLS_EXPORT bool
+spvOptimizerRegisterPassesFromFlagsWhilePreservingTheInterface(
+ spv_optimizer_t* optimizer, const char** flags, const size_t flag_count);
+
// Optimizes the SPIR-V code of size |word_count| pointed to by |binary| and
// returns an optimized spv_binary in |optimized_binary|.
//
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.hpp b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.hpp
index ee6c8469a..59ff82b17 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/libspirv.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/libspirv.hpp
@@ -37,7 +37,7 @@ using InstructionParser =
std::function<spv_result_t(const spv_parsed_instruction_t& instruction)>;
// C++ RAII wrapper around the C context object spv_context.
-class Context {
+class SPIRV_TOOLS_EXPORT Context {
public:
// Constructs a context targeting the given environment |env|.
//
@@ -73,7 +73,7 @@ class Context {
};
// A RAII wrapper around a validator options object.
-class ValidatorOptions {
+class SPIRV_TOOLS_EXPORT ValidatorOptions {
public:
ValidatorOptions() : options_(spvValidatorOptionsCreate()) {}
~ValidatorOptions() { spvValidatorOptionsDestroy(options_); }
@@ -163,7 +163,7 @@ class ValidatorOptions {
};
// A C++ wrapper around an optimization options object.
-class OptimizerOptions {
+class SPIRV_TOOLS_EXPORT OptimizerOptions {
public:
OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {}
~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); }
@@ -205,7 +205,7 @@ class OptimizerOptions {
};
// A C++ wrapper around a reducer options object.
-class ReducerOptions {
+class SPIRV_TOOLS_EXPORT ReducerOptions {
public:
ReducerOptions() : options_(spvReducerOptionsCreate()) {}
~ReducerOptions() { spvReducerOptionsDestroy(options_); }
@@ -236,7 +236,7 @@ class ReducerOptions {
};
// A C++ wrapper around a fuzzer options object.
-class FuzzerOptions {
+class SPIRV_TOOLS_EXPORT FuzzerOptions {
public:
FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {}
~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); }
@@ -283,7 +283,7 @@ class FuzzerOptions {
// provides methods for assembling, disassembling, and validating.
//
// Instances of this class provide basic thread-safety guarantee.
-class SpirvTools {
+class SPIRV_TOOLS_EXPORT SpirvTools {
public:
enum {
// Default assembling option used by assemble():
@@ -388,7 +388,8 @@ class SpirvTools {
bool IsValid() const;
private:
- struct Impl; // Opaque struct for holding the data fields used by this class.
+ struct SPIRV_TOOLS_LOCAL
+ Impl; // Opaque struct for holding the data fields used by this class.
std::unique_ptr<Impl> impl_; // Unique pointer to implementation data.
};
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/linker.hpp b/third_party/SPIRV-Tools/include/spirv-tools/linker.hpp
index d2f3e72ca..6ba6e9654 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/linker.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/linker.hpp
@@ -24,13 +24,8 @@
namespace spvtools {
-class LinkerOptions {
+class SPIRV_TOOLS_EXPORT LinkerOptions {
public:
- LinkerOptions()
- : create_library_(false),
- verify_ids_(false),
- allow_partial_linkage_(false) {}
-
// Returns whether a library or an executable should be produced by the
// linking phase.
//
@@ -63,10 +58,16 @@ class LinkerOptions {
allow_partial_linkage_ = allow_partial_linkage;
}
+ bool GetUseHighestVersion() const { return use_highest_version_; }
+ void SetUseHighestVersion(bool use_highest_vers) {
+ use_highest_version_ = use_highest_vers;
+ }
+
private:
- bool create_library_;
- bool verify_ids_;
- bool allow_partial_linkage_;
+ bool create_library_{false};
+ bool verify_ids_{false};
+ bool allow_partial_linkage_{false};
+ bool use_highest_version_{false};
};
// Links one or more SPIR-V modules into a new SPIR-V module. That is, combine
@@ -83,14 +84,15 @@ class LinkerOptions {
// * Some entry points were defined multiple times;
// * Some imported symbols did not have an exported counterpart;
// * Possibly other reasons.
-spv_result_t Link(const Context& context,
- const std::vector<std::vector<uint32_t>>& binaries,
- std::vector<uint32_t>* linked_binary,
- const LinkerOptions& options = LinkerOptions());
-spv_result_t Link(const Context& context, const uint32_t* const* binaries,
- const size_t* binary_sizes, size_t num_binaries,
- std::vector<uint32_t>* linked_binary,
- const LinkerOptions& options = LinkerOptions());
+SPIRV_TOOLS_EXPORT spv_result_t
+Link(const Context& context, const std::vector<std::vector<uint32_t>>& binaries,
+ std::vector<uint32_t>* linked_binary,
+ const LinkerOptions& options = LinkerOptions());
+SPIRV_TOOLS_EXPORT spv_result_t
+Link(const Context& context, const uint32_t* const* binaries,
+ const size_t* binary_sizes, size_t num_binaries,
+ std::vector<uint32_t>* linked_binary,
+ const LinkerOptions& options = LinkerOptions());
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/linter.hpp b/third_party/SPIRV-Tools/include/spirv-tools/linter.hpp
index 52ed5a467..ccbcf0c17 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/linter.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/linter.hpp
@@ -24,7 +24,7 @@ namespace spvtools {
// provides a method for linting.
//
// Instances of this class provides basic thread-safety guarantee.
-class Linter {
+class SPIRV_TOOLS_EXPORT Linter {
public:
explicit Linter(spv_target_env env);
@@ -40,7 +40,7 @@ class Linter {
bool Run(const uint32_t* binary, size_t binary_size);
private:
- struct Impl;
+ struct SPIRV_TOOLS_LOCAL Impl;
std::unique_ptr<Impl> impl_;
};
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp b/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
index 8bdd4e826..a3119d9b4 100644
--- a/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
+++ b/third_party/SPIRV-Tools/include/spirv-tools/optimizer.hpp
@@ -37,14 +37,14 @@ struct DescriptorSetAndBinding;
// provides methods for registering optimization passes and optimizing.
//
// Instances of this class provides basic thread-safety guarantee.
-class Optimizer {
+class SPIRV_TOOLS_EXPORT Optimizer {
public:
// The token for an optimization pass. It is returned via one of the
// Create*Pass() standalone functions at the end of this header file and
// consumed by the RegisterPass() method. Tokens are one-time objects that
// only support move; copying is not allowed.
struct PassToken {
- struct Impl; // Opaque struct for holding internal data.
+ struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data.
PassToken(std::unique_ptr<Impl>);
@@ -97,12 +97,20 @@ class Optimizer {
// Registers passes that attempt to improve performance of generated code.
// This sequence of passes is subject to constant review and will change
// from time to time.
+ //
+ // If |preserve_interface| is true, all non-io variables in the entry point
+ // interface are considered live and are not eliminated.
Optimizer& RegisterPerformancePasses();
+ Optimizer& RegisterPerformancePasses(bool preserve_interface);
// Registers passes that attempt to improve the size of generated code.
// This sequence of passes is subject to constant review and will change
// from time to time.
+ //
+ // If |preserve_interface| is true, all non-io variables in the entry point
+ // interface are considered live and are not eliminated.
Optimizer& RegisterSizePasses();
+ Optimizer& RegisterSizePasses(bool preserve_interface);
// Registers passes that attempt to legalize the generated code.
//
@@ -112,7 +120,11 @@ class Optimizer {
//
// This sequence of passes is subject to constant review and will change
// from time to time.
+ //
+ // If |preserve_interface| is true, all non-io variables in the entry point
+ // interface are considered live and are not eliminated.
Optimizer& RegisterLegalizationPasses();
+ Optimizer& RegisterLegalizationPasses(bool preserve_interface);
// Register passes specified in the list of |flags|. Each flag must be a
// string of a form accepted by Optimizer::FlagHasValidForm().
@@ -121,8 +133,13 @@ class Optimizer {
// error message is emitted to the MessageConsumer object (use
// Optimizer::SetMessageConsumer to define a message consumer, if needed).
//
+ // If |preserve_interface| is true, all non-io variables in the entry point
+ // interface are considered live and are not eliminated.
+ //
// If all the passes are registered successfully, it returns true.
bool RegisterPassesFromFlags(const std::vector<std::string>& flags);
+ bool RegisterPassesFromFlags(const std::vector<std::string>& flags,
+ bool preserve_interface);
// Registers the optimization pass associated with |flag|. This only accepts
// |flag| values of the form "--pass_name[=pass_args]". If no such pass
@@ -139,7 +156,11 @@ class Optimizer {
//
// --legalize-hlsl: Registers all passes that legalize SPIR-V generated by an
// HLSL front-end.
+ //
+ // If |preserve_interface| is true, all non-io variables in the entry point
+ // interface are considered live and are not eliminated.
bool RegisterPassFromFlag(const std::string& flag);
+ bool RegisterPassFromFlag(const std::string& flag, bool preserve_interface);
// Validates that |flag| has a valid format. Strings accepted:
//
@@ -218,7 +239,7 @@ class Optimizer {
Optimizer& SetValidateAfterAll(bool validate);
private:
- struct Impl; // Opaque struct for holding internal data.
+ struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data.
std::unique_ptr<Impl> impl_; // Unique pointer to internal data.
};
@@ -748,19 +769,9 @@ Optimizer::PassToken CreateCombineAccessChainsPass();
// potentially de-optimizing the instrument code, for example, inlining
// the debug record output function throughout the module.
//
-// The instrumentation will read and write buffers in debug
-// descriptor set |desc_set|. It will write |shader_id| in each output record
+// The instrumentation will write |shader_id| in each output record
// to identify the shader module which generated the record.
-// |desc_length_enable| controls instrumentation of runtime descriptor array
-// references, |desc_init_enable| controls instrumentation of descriptor
-// initialization checking, and |buff_oob_enable| controls instrumentation
-// of storage and uniform buffer bounds checking, all of which require input
-// buffer support. |texbuff_oob_enable| controls instrumentation of texel
-// buffers, which does not require input buffer support.
-Optimizer::PassToken CreateInstBindlessCheckPass(
- uint32_t desc_set, uint32_t shader_id, bool desc_length_enable = false,
- bool desc_init_enable = false, bool buff_oob_enable = false,
- bool texbuff_oob_enable = false);
+Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id);
// Create a pass to instrument physical buffer address checking
// This pass instruments all physical buffer address references to check that
@@ -781,8 +792,7 @@ Optimizer::PassToken CreateInstBindlessCheckPass(
// The instrumentation will read and write buffers in debug
// descriptor set |desc_set|. It will write |shader_id| in each output record
// to identify the shader module which generated the record.
-Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t desc_set,
- uint32_t shader_id);
+Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id);
// Create a pass to instrument OpDebugPrintf instructions.
// This pass replaces all OpDebugPrintf instructions with instructions to write
@@ -971,6 +981,32 @@ Optimizer::PassToken CreateRemoveDontInlinePass();
// object, currently the pass would remove accesschain pointer argument passed
// to the function
Optimizer::PassToken CreateFixFuncCallArgumentsPass();
+
+// Creates a trim-capabilities pass.
+// This pass removes unused capabilities for a given module, and if possible,
+// associated extensions.
+// See `trim_capabilities.h` for the list of supported capabilities.
+//
+// If the module contains unsupported capabilities, this pass will ignore them.
+// This should be fine in most cases, but could yield to incorrect results if
+// the unknown capability interacts with one of the trimmed capabilities.
+Optimizer::PassToken CreateTrimCapabilitiesPass();
+
+// Creates a switch-descriptorset pass.
+// This pass changes any DescriptorSet decorations with the value |ds_from| to
+// use the new value |ds_to|.
+Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t ds_from,
+ uint32_t ds_to);
+
+// Creates an invocation interlock placement pass.
+// This pass ensures that an entry point will have at most one
+// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that
+// order.
+Optimizer::PassToken CreateInvocationInterlockPlacementPass();
+
+// Creates a pass to add/remove maximal reconvergence execution mode.
+// This pass either adds or removes maximal reconvergence from all entry points.
+Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add);
} // namespace spvtools
#endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_
diff --git a/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh b/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
index 2465d9c60..4bb889ad0 100644
--- a/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
+++ b/third_party/SPIRV-Tools/kokoro/macos-clang-release-bazel/build.sh
@@ -30,20 +30,16 @@ SRC=$PWD/github/SPIRV-Tools
git config --global --add safe.directory $SRC
cd $SRC
-git clone --depth=1 https://github.com/KhronosGroup/SPIRV-Headers external/spirv-headers
-git clone https://github.com/google/googletest external/googletest
-cd external && cd googletest && git reset --hard 1fb1bb23bb8418dc73a5a9a82bbed31dc610fec7 && cd .. && cd ..
-git clone --depth=1 https://github.com/google/effcee external/effcee
-git clone --depth=1 https://github.com/google/re2 external/re2
+/usr/bin/python3 utils/git-sync-deps --treeless
-# Get bazel 5.0.0
-gsutil cp gs://bazel/5.0.0/release/bazel-5.0.0-darwin-x86_64 .
-chmod +x bazel-5.0.0-darwin-x86_64
+# Get bazel 7.0.2
+gsutil cp gs://bazel/7.0.2/release/bazel-7.0.2-darwin-x86_64 .
+chmod +x bazel-7.0.2-darwin-x86_64
echo $(date): Build everything...
-./bazel-5.0.0-darwin-x86_64 build --cxxopt=-std=c++17 :all
+./bazel-7.0.2-darwin-x86_64 build --cxxopt=-std=c++17 :all
echo $(date): Build completed.
echo $(date): Starting bazel test...
-./bazel-5.0.0-darwin-x86_64 test --cxxopt=-std=c++17 :all
+./bazel-7.0.2-darwin-x86_64 test --cxxopt=-std=c++17 :all
echo $(date): Bazel test completed.
diff --git a/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh b/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
index f2a06e07c..e47037d54 100755
--- a/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
+++ b/third_party/SPIRV-Tools/kokoro/scripts/linux/build-docker.sh
@@ -131,6 +131,7 @@ elif [ $TOOL = "cmake-smoketest" ]; then
git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers
git clone https://github.com/google/re2
git clone https://github.com/google/effcee
+ git clone https://github.com/abseil/abseil-cpp abseil_cpp
cd $SHADERC_DIR
mkdir build
@@ -141,7 +142,7 @@ elif [ $TOOL = "cmake-smoketest" ]; then
cmake -GNinja -DRE2_BUILD_TESTING=OFF -DCMAKE_BUILD_TYPE="Release" ..
echo $(date): Build glslang...
- ninja glslangValidator
+ ninja glslang-standalone
echo $(date): Build everything...
ninja
@@ -155,7 +156,7 @@ elif [ $TOOL = "cmake-smoketest" ]; then
echo $(date): ctest completed.
elif [ $TOOL = "cmake-android-ndk" ]; then
using cmake-3.17.2
- using ndk-r21d
+ using ndk-r25c
using ninja-1.10.0
clean_dir "$ROOT_DIR/build"
@@ -163,7 +164,7 @@ elif [ $TOOL = "cmake-android-ndk" ]; then
echo $(date): Starting build...
cmake -DCMAKE_BUILD_TYPE=Release \
- -DANDROID_NATIVE_API_LEVEL=android-16 \
+ -DANDROID_NATIVE_API_LEVEL=android-24 \
-DANDROID_ABI="armeabi-v7a with NEON" \
-DSPIRV_SKIP_TESTS=ON \
-DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" \
@@ -175,7 +176,7 @@ elif [ $TOOL = "cmake-android-ndk" ]; then
ninja
echo $(date): Build completed.
elif [ $TOOL = "android-ndk-build" ]; then
- using ndk-r21d
+ using ndk-r25c
clean_dir "$ROOT_DIR/build"
cd "$ROOT_DIR/build"
@@ -190,7 +191,7 @@ elif [ $TOOL = "android-ndk-build" ]; then
echo $(date): ndk-build completed.
elif [ $TOOL = "bazel" ]; then
- using bazel-5.0.0
+ using bazel-7.0.2
echo $(date): Build everything...
bazel build --cxxopt=-std=c++17 :all
diff --git a/third_party/SPIRV-Tools/kokoro/scripts/windows/build.bat b/third_party/SPIRV-Tools/kokoro/scripts/windows/build.bat
index bb14da3dc..fe15f2d79 100644
--- a/third_party/SPIRV-Tools/kokoro/scripts/windows/build.bat
+++ b/third_party/SPIRV-Tools/kokoro/scripts/windows/build.bat
@@ -30,6 +30,9 @@ set PATH=C:\python36;"C:\Program Files\cmake-3.23.1-windows-x86_64\bin";%PATH%
if %VS_VERSION% == 2017 (
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
echo "Using VS 2017..."
+
+ :: RE2 does not support VS2017, we we must disable tests.
+ set BUILD_TESTS=NO
) else if %VS_VERSION% == 2019 (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
echo "Using VS 2019..."
@@ -56,6 +59,10 @@ set CMAKE_FLAGS=-DCMAKE_INSTALL_PREFIX=%KOKORO_ARTIFACTS_DIR%\install -GNinja -D
:: Build spirv-fuzz
set CMAKE_FLAGS=%CMAKE_FLAGS% -DSPIRV_BUILD_FUZZER=ON
+if "%BUILD_TESTS%" == "NO" (
+ set CMAKE_FLAGS=-DSPIRV_SKIP_TESTS=ON %CMAKE_FLAGS%
+)
+
cmake %CMAKE_FLAGS% ..
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
@@ -71,10 +78,12 @@ setlocal ENABLEDELAYEDEXPANSION
:: ################################################
:: Run the tests
:: ################################################
-echo "Running Tests... %DATE% %TIME%"
-ctest -C %BUILD_TYPE% --output-on-failure --timeout 300
-if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!
-echo "Tests Completed %DATE% %TIME%"
+if "%BUILD_TESTS%" NEQ "NO" (
+ echo "Running Tests... %DATE% %TIME%"
+ ctest -C %BUILD_TYPE% --output-on-failure --timeout 300
+ if !ERRORLEVEL! NEQ 0 exit /b !ERRORLEVEL!
+ echo "Tests Completed %DATE% %TIME%"
+)
:: ################################################
:: Install and package.
diff --git a/third_party/SPIRV-Tools/source/CMakeLists.txt b/third_party/SPIRV-Tools/source/CMakeLists.txt
index acfa0c123..d0454c6c7 100644
--- a/third_party/SPIRV-Tools/source/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/CMakeLists.txt
@@ -31,7 +31,7 @@ macro(spvtools_core_tables CONFIG_VERSION)
set(GRAMMAR_INSTS_INC_FILE "${spirv-tools_BINARY_DIR}/core.insts-${CONFIG_VERSION}.inc")
set(GRAMMAR_KINDS_INC_FILE "${spirv-tools_BINARY_DIR}/operand.kinds-${CONFIG_VERSION}.inc")
add_custom_command(OUTPUT ${GRAMMAR_INSTS_INC_FILE} ${GRAMMAR_KINDS_INC_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
@@ -53,7 +53,7 @@ macro(spvtools_enum_string_mapping CONFIG_VERSION)
set(GRAMMAR_ENUM_STRING_MAPPING_INC_FILE "${spirv-tools_BINARY_DIR}/enum_string_mapping.inc")
add_custom_command(OUTPUT ${GRAMMAR_EXTENSION_ENUM_INC_FILE}
${GRAMMAR_ENUM_STRING_MAPPING_INC_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-cldebuginfo100-grammar=${CLDEBUGINFO100_GRAMMAR_JSON_FILE}
@@ -75,7 +75,7 @@ macro(spvtools_vimsyntax CONFIG_VERSION CLVERSION)
set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json")
set(VIMSYNTAX_FILE "${spirv-tools_BINARY_DIR}/spvasm.vim")
add_custom_command(OUTPUT ${VIMSYNTAX_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${VIMSYNTAX_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${VIMSYNTAX_PROCESSING_SCRIPT}
--spirv-core-grammar=${GRAMMAR_JSON_FILE}
--extinst-debuginfo-grammar=${DEBUGINFO_GRAMMAR_JSON_FILE}
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
@@ -91,7 +91,7 @@ macro(spvtools_glsl_tables CONFIG_VERSION)
set(GLSL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.glsl.std.450.grammar.json")
set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/glsl.std.450.insts.inc")
add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-glsl-grammar=${GLSL_GRAMMAR_JSON_FILE}
--glsl-insts-output=${GRAMMAR_INC_FILE}
--output-language=c++
@@ -105,7 +105,7 @@ macro(spvtools_opencl_tables CONFIG_VERSION)
set(OPENCL_GRAMMAR_JSON_FILE "${SPIRV_HEADER_INCLUDE_DIR}/spirv/${CONFIG_VERSION}/extinst.opencl.std.100.grammar.json")
set(GRAMMAR_INC_FILE "${spirv-tools_BINARY_DIR}/opencl.std.insts.inc")
add_custom_command(OUTPUT ${GRAMMAR_INC_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-opencl-grammar=${OPENCL_GRAMMAR_JSON_FILE}
--opencl-insts-output=${GRAMMAR_INC_FILE}
DEPENDS ${GRAMMAR_PROCESSING_SCRIPT} ${CORE_GRAMMAR_JSON_FILE} ${OPENCL_GRAMMAR_JSON_FILE}
@@ -120,7 +120,7 @@ macro(spvtools_vendor_tables VENDOR_TABLE SHORT_NAME OPERAND_KIND_PREFIX)
set(GRAMMAR_FILE "${spirv-tools_SOURCE_DIR}/source/extinst.${VENDOR_TABLE}.grammar.json")
endif()
add_custom_command(OUTPUT ${INSTS_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${GRAMMAR_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${GRAMMAR_PROCESSING_SCRIPT}
--extinst-vendor-grammar=${GRAMMAR_FILE}
--vendor-insts-output=${INSTS_FILE}
--vendor-operand-kind-prefix=${OPERAND_KIND_PREFIX}
@@ -134,7 +134,7 @@ endmacro(spvtools_vendor_tables)
macro(spvtools_extinst_lang_headers NAME GRAMMAR_FILE)
set(OUT_H ${spirv-tools_BINARY_DIR}/${NAME}.h)
add_custom_command(OUTPUT ${OUT_H}
- COMMAND ${PYTHON_EXECUTABLE} ${LANG_HEADER_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${LANG_HEADER_PROCESSING_SCRIPT}
--extinst-grammar=${GRAMMAR_FILE}
--extinst-output-path=${OUT_H}
DEPENDS ${LANG_HEADER_PROCESSING_SCRIPT} ${GRAMMAR_FILE}
@@ -156,6 +156,7 @@ spvtools_vendor_tables("debuginfo" "debuginfo" "")
spvtools_vendor_tables("opencl.debuginfo.100" "cldi100" "CLDEBUG100_")
spvtools_vendor_tables("nonsemantic.shader.debuginfo.100" "shdi100" "SHDEBUG100_")
spvtools_vendor_tables("nonsemantic.clspvreflection" "clspvreflection" "")
+spvtools_vendor_tables("nonsemantic.vkspreflection" "vkspreflection" "")
spvtools_extinst_lang_headers("DebugInfo" ${DEBUGINFO_GRAMMAR_JSON_FILE})
spvtools_extinst_lang_headers("OpenCLDebugInfo100" ${CLDEBUGINFO100_GRAMMAR_JSON_FILE})
spvtools_extinst_lang_headers("NonSemanticShaderDebugInfo100" ${VKDEBUGINFO100_GRAMMAR_JSON_FILE})
@@ -168,7 +169,7 @@ set_property(TARGET spirv-tools-vimsyntax PROPERTY FOLDER "SPIRV-Tools utilities
set(GENERATOR_INC_FILE ${spirv-tools_BINARY_DIR}/generators.inc)
set(SPIRV_XML_REGISTRY_FILE ${SPIRV_HEADER_INCLUDE_DIR}/spirv/spir-v.xml)
add_custom_command(OUTPUT ${GENERATOR_INC_FILE}
- COMMAND ${PYTHON_EXECUTABLE} ${XML_REGISTRY_PROCESSING_SCRIPT}
+ COMMAND Python3::Interpreter ${XML_REGISTRY_PROCESSING_SCRIPT}
--xml=${SPIRV_XML_REGISTRY_FILE}
--generator-output=${GENERATOR_INC_FILE}
DEPENDS ${XML_REGISTRY_PROCESSING_SCRIPT} ${SPIRV_XML_REGISTRY_FILE}
@@ -198,7 +199,7 @@ set(SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR
set(SPIRV_TOOLS_CHANGES_FILE
${spirv-tools_SOURCE_DIR}/CHANGES)
add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC}
- COMMAND ${PYTHON_EXECUTABLE}
+ COMMAND Python3::Interpreter
${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
${SPIRV_TOOLS_CHANGES_FILE} ${SPIRV_TOOLS_BUILD_VERSION_INC}
DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC_GENERATOR}
@@ -418,12 +419,6 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
endif()
endif()
-if (ANDROID)
- foreach(target ${SPIRV_TOOLS_TARGETS})
- target_link_libraries(${target} PRIVATE android log)
- endforeach()
-endif()
-
if(ENABLE_SPIRV_TOOLS_INSTALL)
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets)
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
diff --git a/third_party/SPIRV-Tools/source/assembly_grammar.cpp b/third_party/SPIRV-Tools/source/assembly_grammar.cpp
index 6df823e30..0092d01a5 100644
--- a/third_party/SPIRV-Tools/source/assembly_grammar.cpp
+++ b/third_party/SPIRV-Tools/source/assembly_grammar.cpp
@@ -21,6 +21,7 @@
#include "source/ext_inst.h"
#include "source/opcode.h"
#include "source/operand.h"
+#include "source/spirv_target_env.h"
#include "source/table.h"
namespace spvtools {
@@ -154,11 +155,12 @@ const SpecConstantOpcodeEntry kOpSpecConstantOpcodes[] = {
CASE(InBoundsAccessChain),
CASE(PtrAccessChain),
CASE(InBoundsPtrAccessChain),
- CASE(CooperativeMatrixLengthNV)
+ CASE(CooperativeMatrixLengthNV),
+ CASE(CooperativeMatrixLengthKHR)
};
// The 60 is determined by counting the opcodes listed in the spec.
-static_assert(60 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]),
+static_assert(61 == sizeof(kOpSpecConstantOpcodes)/sizeof(kOpSpecConstantOpcodes[0]),
"OpSpecConstantOp opcode table is incomplete");
#undef CASE
// clang-format on
@@ -175,15 +177,18 @@ bool AssemblyGrammar::isValid() const {
CapabilitySet AssemblyGrammar::filterCapsAgainstTargetEnv(
const spv::Capability* cap_array, uint32_t count) const {
CapabilitySet cap_set;
+ const auto version = spvVersionForTargetEnv(target_env_);
for (uint32_t i = 0; i < count; ++i) {
- spv_operand_desc cap_desc = {};
+ spv_operand_desc entry = {};
if (SPV_SUCCESS == lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
static_cast<uint32_t>(cap_array[i]),
- &cap_desc)) {
- // spvOperandTableValueLookup() filters capabilities internally
- // according to the current target environment by itself. So we
- // should be safe to add this capability if the lookup succeeds.
- cap_set.Add(cap_array[i]);
+ &entry)) {
+ // This token is visible in this environment if it's in an appropriate
+ // core version, or it is enabled by a capability or an extension.
+ if ((version >= entry->minVersion && version <= entry->lastVersion) ||
+ entry->numExtensions > 0u || entry->numCapabilities > 0u) {
+ cap_set.insert(cap_array[i]);
+ }
}
}
return cap_set;
diff --git a/third_party/SPIRV-Tools/source/binary.cpp b/third_party/SPIRV-Tools/source/binary.cpp
index beb56be7b..cf1f0b7b0 100644
--- a/third_party/SPIRV-Tools/source/binary.cpp
+++ b/third_party/SPIRV-Tools/source/binary.cpp
@@ -546,6 +546,13 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
parsed_operand.number_bit_width = 32;
break;
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT:
+ // These are regular single-word literal float operands.
+ parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_FLOAT;
+ parsed_operand.number_kind = SPV_NUMBER_FLOATING;
+ parsed_operand.number_bit_width = 32;
+ break;
+
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
@@ -626,7 +633,6 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
} break;
case SPV_OPERAND_TYPE_CAPABILITY:
- case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
case SPV_OPERAND_TYPE_EXECUTION_MODEL:
case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
case SPV_OPERAND_TYPE_MEMORY_MODEL:
@@ -664,7 +670,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
case SPV_OPERAND_TYPE_OVERFLOW_MODES:
case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
- case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: {
+ case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
+ case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: {
// A single word that is a plain enum value.
// Map an optional operand type to its corresponding concrete type.
@@ -683,22 +690,44 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
spvPushOperandTypes(entry->operandTypes, expected_operands);
} break;
+ case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: {
+ spv_operand_desc entry;
+ if (grammar_.lookupOperand(type, word, &entry)) {
+ return diagnostic()
+ << "Invalid " << spvOperandTypeStr(parsed_operand.type)
+ << " operand: " << word
+ << ", if you are creating a new source language please use "
+ "value 0 "
+ "(Unknown) and when ready, add your source language to "
+ "SPRIV-Headers";
+ }
+ // Prepare to accept operands to this operand, if needed.
+ spvPushOperandTypes(entry->operandTypes, expected_operands);
+ } break;
+
case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
case SPV_OPERAND_TYPE_LOOP_CONTROL:
case SPV_OPERAND_TYPE_IMAGE:
case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
+ case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
case SPV_OPERAND_TYPE_SELECTION_CONTROL:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
- case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: {
+ case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
+ case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: {
// This operand is a mask.
// Map an optional operand type to its corresponding concrete type.
if (type == SPV_OPERAND_TYPE_OPTIONAL_IMAGE)
parsed_operand.type = SPV_OPERAND_TYPE_IMAGE;
- else if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS)
+ if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS)
parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS;
+ if (type == SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS)
+ parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS;
+ if (type == SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS)
+ parsed_operand.type = SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS;
// Check validity of set mask bits. Also prepare for operands for those
// masks if they have any. To get operand order correct, scan from
diff --git a/third_party/SPIRV-Tools/source/diff/diff.cpp b/third_party/SPIRV-Tools/source/diff/diff.cpp
index 6daed321d..6269af500 100644
--- a/third_party/SPIRV-Tools/source/diff/diff.cpp
+++ b/third_party/SPIRV-Tools/source/diff/diff.cpp
@@ -101,9 +101,12 @@ class IdMap {
return from < id_map_.size() && id_map_[from] != 0;
}
- // Map any ids in src and dst that have not been mapped to new ids in dst and
- // src respectively.
- void MapUnmatchedIds(IdMap& other_way);
+ bool IsMapped(const opt::Instruction* from_inst) const {
+ assert(from_inst != nullptr);
+ assert(!from_inst->HasResultId());
+
+ return inst_map_.find(from_inst) != inst_map_.end();
+ }
// Some instructions don't have result ids. Those are mapped by pointer.
void MapInsts(const opt::Instruction* from_inst,
@@ -117,6 +120,12 @@ class IdMap {
uint32_t IdBound() const { return static_cast<uint32_t>(id_map_.size()); }
+ // Generate a fresh id in this mapping's domain.
+ uint32_t MakeFreshId() {
+ id_map_.push_back(0);
+ return static_cast<uint32_t>(id_map_.size()) - 1;
+ }
+
private:
// Given an id, returns the corresponding id in the other module, or 0 if not
// matched yet.
@@ -150,10 +159,16 @@ class SrcDstIdMap {
bool IsSrcMapped(uint32_t src) { return src_to_dst_.IsMapped(src); }
bool IsDstMapped(uint32_t dst) { return dst_to_src_.IsMapped(dst); }
+ bool IsDstMapped(const opt::Instruction* dst_inst) {
+ return dst_to_src_.IsMapped(dst_inst);
+ }
// Map any ids in src and dst that have not been mapped to new ids in dst and
- // src respectively.
- void MapUnmatchedIds();
+ // src respectively. Use src_insn_defined and dst_insn_defined to ignore ids
+ // that are simply never defined. (Since we assume the inputs are valid
+ // SPIR-V, this implies they are also never used.)
+ void MapUnmatchedIds(std::function<bool(uint32_t)> src_insn_defined,
+ std::function<bool(uint32_t)> dst_insn_defined);
// Some instructions don't have result ids. Those are mapped by pointer.
void MapInsts(const opt::Instruction* src_inst,
@@ -203,6 +218,11 @@ struct IdInstructions {
void MapIdToInstruction(uint32_t id, const opt::Instruction* inst);
+ // Return true if id is mapped to any instruction, false otherwise.
+ bool IsDefined(uint32_t id) {
+ return id < inst_map_.size() && inst_map_[id] != nullptr;
+ }
+
void MapIdsToInstruction(
opt::IteratorRange<opt::Module::const_inst_iterator> section);
void MapIdsToInfos(
@@ -338,6 +358,59 @@ class Differ {
std::function<void(const IdGroup& src_group, const IdGroup& dst_group)>
match_group);
+ // Bucket `src_ids` and `dst_ids` by the key ids returned by `get_group`, and
+ // then call `match_group` on pairs of buckets whose key ids are matched with
+ // each other.
+ //
+ // For example, suppose we want to pair up groups of instructions with the
+ // same type. Naturally, the source instructions refer to their types by their
+ // ids in the source, and the destination instructions use destination type
+ // ids, so simply comparing source and destination type ids as integers, as
+ // `GroupIdsAndMatch` would do, is meaningless. But if a prior call to
+ // `MatchTypeIds` has established type matches between the two modules, then
+ // we can consult those to pair source and destination buckets whose types are
+ // equivalent.
+ //
+ // Suppose our input groups are as follows:
+ //
+ // - src_ids: { 1 -> 100, 2 -> 300, 3 -> 100, 4 -> 200 }
+ // - dst_ids: { 5 -> 10, 6 -> 20, 7 -> 10, 8 -> 300 }
+ //
+ // Here, `X -> Y` means that the instruction with SPIR-V id `X` is a member of
+ // the group, and `Y` is the id of its type. If we use
+ // `Differ::GroupIdsHelperGetTypeId` for `get_group`, then
+ // `get_group(X) == Y`.
+ //
+ // These instructions are bucketed by type as follows:
+ //
+ // - source: [1, 3] -> 100
+ // [4] -> 200
+ // [2] -> 300
+ //
+ // - destination: [5, 7] -> 10
+ // [6] -> 20
+ // [8] -> 300
+ //
+ // Now suppose that we have previously matched up src type 100 with dst type
+ // 10, and src type 200 with dst type 20, but no other types are matched.
+ //
+ // Then `match_group` is called twice:
+ // - Once with ([1,3], [5, 7]), corresponding to 100/10
+ // - Once with ([4],[6]), corresponding to 200/20
+ //
+ // The source type 300 isn't matched with anything, so the fact that there's a
+ // destination type 300 is irrelevant, and thus 2 and 8 are never passed to
+ // `match_group`.
+ //
+ // This function isn't specific to types; it simply buckets by the ids
+ // returned from `get_group`, and consults existing matches to pair up the
+ // resulting buckets.
+ void GroupIdsAndMatchByMappedId(
+ const IdGroup& src_ids, const IdGroup& dst_ids,
+ uint32_t (Differ::*get_group)(const IdInstructions&, uint32_t),
+ std::function<void(const IdGroup& src_group, const IdGroup& dst_group)>
+ match_group);
+
// Helper functions that determine if two instructions match
bool DoIdsMatch(uint32_t src_id, uint32_t dst_id);
bool DoesOperandMatch(const opt::Operand& src_operand,
@@ -504,36 +577,27 @@ class Differ {
FunctionMap dst_funcs_;
};
-void IdMap::MapUnmatchedIds(IdMap& other_way) {
- const uint32_t src_id_bound = static_cast<uint32_t>(id_map_.size());
- const uint32_t dst_id_bound = static_cast<uint32_t>(other_way.id_map_.size());
-
- uint32_t next_src_id = src_id_bound;
- uint32_t next_dst_id = dst_id_bound;
+void SrcDstIdMap::MapUnmatchedIds(
+ std::function<bool(uint32_t)> src_insn_defined,
+ std::function<bool(uint32_t)> dst_insn_defined) {
+ const uint32_t src_id_bound = static_cast<uint32_t>(src_to_dst_.IdBound());
+ const uint32_t dst_id_bound = static_cast<uint32_t>(dst_to_src_.IdBound());
for (uint32_t src_id = 1; src_id < src_id_bound; ++src_id) {
- if (!IsMapped(src_id)) {
- MapIds(src_id, next_dst_id);
-
- other_way.id_map_.push_back(0);
- other_way.MapIds(next_dst_id++, src_id);
+ if (!src_to_dst_.IsMapped(src_id) && src_insn_defined(src_id)) {
+ uint32_t fresh_dst_id = dst_to_src_.MakeFreshId();
+ MapIds(src_id, fresh_dst_id);
}
}
for (uint32_t dst_id = 1; dst_id < dst_id_bound; ++dst_id) {
- if (!other_way.IsMapped(dst_id)) {
- id_map_.push_back(0);
- MapIds(next_src_id, dst_id);
-
- other_way.MapIds(dst_id, next_src_id++);
+ if (!dst_to_src_.IsMapped(dst_id) && dst_insn_defined(dst_id)) {
+ uint32_t fresh_src_id = src_to_dst_.MakeFreshId();
+ MapIds(fresh_src_id, dst_id);
}
}
}
-void SrcDstIdMap::MapUnmatchedIds() {
- src_to_dst_.MapUnmatchedIds(dst_to_src_);
-}
-
void IdInstructions::MapIdToInstruction(uint32_t id,
const opt::Instruction* inst) {
assert(id != 0);
@@ -889,6 +953,37 @@ void Differ::GroupIdsAndMatch(
}
}
+void Differ::GroupIdsAndMatchByMappedId(
+ const IdGroup& src_ids, const IdGroup& dst_ids,
+ uint32_t (Differ::*get_group)(const IdInstructions&, uint32_t),
+ std::function<void(const IdGroup& src_group, const IdGroup& dst_group)>
+ match_group) {
+ // Group the ids based on a key (get_group)
+ std::map<uint32_t, IdGroup> src_groups;
+ std::map<uint32_t, IdGroup> dst_groups;
+
+ GroupIds<uint32_t>(src_ids, true, &src_groups, get_group);
+ GroupIds<uint32_t>(dst_ids, false, &dst_groups, get_group);
+
+ // Iterate over pairs of groups whose keys map to each other.
+ for (const auto& iter : src_groups) {
+ const uint32_t& src_key = iter.first;
+ const IdGroup& src_group = iter.second;
+
+ if (src_key == 0) {
+ continue;
+ }
+
+ if (id_map_.IsSrcMapped(src_key)) {
+ const uint32_t& dst_key = id_map_.MappedDstId(src_key);
+ const IdGroup& dst_group = dst_groups[dst_key];
+
+ // Let the caller match the groups as appropriate.
+ match_group(src_group, dst_group);
+ }
+ }
+}
+
bool Differ::DoIdsMatch(uint32_t src_id, uint32_t dst_id) {
assert(dst_id != 0);
return id_map_.MappedDstId(src_id) == dst_id;
@@ -1419,7 +1514,6 @@ void Differ::MatchTypeForwardPointersByName(const IdGroup& src,
GroupIdsAndMatch<std::string>(
src, dst, "", &Differ::GetSanitizedName,
[this](const IdGroup& src_group, const IdGroup& dst_group) {
-
// Match only if there's a unique forward declaration with this debug
// name.
if (src_group.size() == 1 && dst_group.size() == 1) {
@@ -1574,6 +1668,8 @@ void Differ::BestEffortMatchFunctions(const IdGroup& src_func_ids,
id_map_.MapIds(match_result.src_id, match_result.dst_id);
+ MatchFunctionParamIds(src_funcs_[match_result.src_id],
+ dst_funcs_[match_result.dst_id]);
MatchIdsInFunctionBodies(src_func_insts.at(match_result.src_id),
dst_func_insts.at(match_result.dst_id),
match_result.src_match, match_result.dst_match, 0);
@@ -1598,7 +1694,6 @@ void Differ::MatchFunctionParamIds(const opt::Function* src_func,
GroupIdsAndMatch<std::string>(
src_params, dst_params, "", &Differ::GetSanitizedName,
[this](const IdGroup& src_group, const IdGroup& dst_group) {
-
// There shouldn't be two parameters with the same name, so the ids
// should match. There is nothing restricting the SPIR-V however to have
// two parameters with the same name, so be resilient against that.
@@ -1609,17 +1704,17 @@ void Differ::MatchFunctionParamIds(const opt::Function* src_func,
// Then match the parameters by their type. If there are multiple of them,
// match them by their order.
- GroupIdsAndMatch<uint32_t>(
- src_params, dst_params, 0, &Differ::GroupIdsHelperGetTypeId,
+ GroupIdsAndMatchByMappedId(
+ src_params, dst_params, &Differ::GroupIdsHelperGetTypeId,
[this](const IdGroup& src_group_by_type_id,
const IdGroup& dst_group_by_type_id) {
-
const size_t shared_param_count =
std::min(src_group_by_type_id.size(), dst_group_by_type_id.size());
for (size_t param_index = 0; param_index < shared_param_count;
++param_index) {
- id_map_.MapIds(src_group_by_type_id[0], dst_group_by_type_id[0]);
+ id_map_.MapIds(src_group_by_type_id[param_index],
+ dst_group_by_type_id[param_index]);
}
});
}
@@ -1943,6 +2038,10 @@ spv_number_kind_t Differ::GetNumberKind(const IdInstructions& id_to,
// Always unsigned integers.
*number_bit_width = 32;
return SPV_NUMBER_UNSIGNED_INT;
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT:
+ // Always float.
+ *number_bit_width = 32;
+ return SPV_NUMBER_FLOATING;
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
switch (inst.opcode()) {
@@ -2064,9 +2163,10 @@ void Differ::MatchEntryPointIds() {
}
// Otherwise match them by name.
- bool matched = false;
for (const opt::Instruction* src_inst : src_insts) {
for (const opt::Instruction* dst_inst : dst_insts) {
+ if (id_map_.IsDstMapped(dst_inst)) continue;
+
const opt::Operand& src_name = src_inst->GetOperand(2);
const opt::Operand& dst_name = dst_inst->GetOperand(2);
@@ -2075,13 +2175,9 @@ void Differ::MatchEntryPointIds() {
uint32_t dst_id = dst_inst->GetSingleWordOperand(1);
id_map_.MapIds(src_id, dst_id);
id_map_.MapInsts(src_inst, dst_inst);
- matched = true;
break;
}
}
- if (matched) {
- break;
- }
}
}
}
@@ -2126,7 +2222,6 @@ void Differ::MatchTypeForwardPointers() {
spv::StorageClass::Max, &Differ::GroupIdsHelperGetTypePointerStorageClass,
[this](const IdGroup& src_group_by_storage_class,
const IdGroup& dst_group_by_storage_class) {
-
// Group them further by the type they are pointing to and loop over
// them.
GroupIdsAndMatch<spv::Op>(
@@ -2134,7 +2229,6 @@ void Differ::MatchTypeForwardPointers() {
spv::Op::Max, &Differ::GroupIdsHelperGetTypePointerTypeOp,
[this](const IdGroup& src_group_by_type_op,
const IdGroup& dst_group_by_type_op) {
-
// Group them even further by debug info, if possible and match by
// debug name.
MatchTypeForwardPointersByName(src_group_by_type_op,
@@ -2199,7 +2293,9 @@ void Differ::MatchTypeIds() {
case spv::Op::OpTypeVoid:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeSampler:
- // void, bool and sampler are unique, match them.
+ case spv::Op::OpTypeAccelerationStructureNV:
+ case spv::Op::OpTypeRayQueryKHR:
+ // the above types have no operands and are unique, match them.
return true;
case spv::Op::OpTypeInt:
case spv::Op::OpTypeFloat:
@@ -2378,7 +2474,6 @@ void Differ::MatchFunctions() {
GroupIdsAndMatch<std::string>(
src_func_ids, dst_func_ids, "", &Differ::GetSanitizedName,
[this](const IdGroup& src_group, const IdGroup& dst_group) {
-
// If there is a single function with this name in src and dst, it's a
// definite match.
if (src_group.size() == 1 && dst_group.size() == 1) {
@@ -2392,7 +2487,6 @@ void Differ::MatchFunctions() {
&Differ::GroupIdsHelperGetTypeId,
[this](const IdGroup& src_group_by_type_id,
const IdGroup& dst_group_by_type_id) {
-
if (src_group_by_type_id.size() == 1 &&
dst_group_by_type_id.size() == 1) {
id_map_.MapIds(src_group_by_type_id[0],
@@ -2437,7 +2531,6 @@ void Differ::MatchFunctions() {
src_func_ids, dst_func_ids, 0, &Differ::GroupIdsHelperGetTypeId,
[this](const IdGroup& src_group_by_type_id,
const IdGroup& dst_group_by_type_id) {
-
BestEffortMatchFunctions(src_group_by_type_id, dst_group_by_type_id,
src_func_insts_, dst_func_insts_);
});
@@ -2647,7 +2740,9 @@ opt::Instruction Differ::ToMappedSrcIds(const opt::Instruction& dst_inst) {
}
spv_result_t Differ::Output() {
- id_map_.MapUnmatchedIds();
+ id_map_.MapUnmatchedIds(
+ [this](uint32_t src_id) { return src_id_to_.IsDefined(src_id); },
+ [this](uint32_t dst_id) { return dst_id_to_.IsDefined(dst_id); });
src_id_to_.inst_map_.resize(id_map_.SrcToDstMap().IdBound(), nullptr);
dst_id_to_.inst_map_.resize(id_map_.DstToSrcMap().IdBound(), nullptr);
diff --git a/third_party/SPIRV-Tools/source/disassemble.cpp b/third_party/SPIRV-Tools/source/disassemble.cpp
index f862efd56..f8f6f44a3 100644
--- a/third_party/SPIRV-Tools/source/disassemble.cpp
+++ b/third_party/SPIRV-Tools/source/disassemble.cpp
@@ -357,7 +357,8 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
stream_ << opcode_desc->name;
} break;
case SPV_OPERAND_TYPE_LITERAL_INTEGER:
- case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: {
+ case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT: {
SetRed();
EmitNumericLiteral(&stream_, inst, operand);
ResetColor();
@@ -424,6 +425,7 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst,
case SPV_OPERAND_TYPE_SELECTION_CONTROL:
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
+ case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
EmitMaskOperand(operand.type, word);
break;
default:
diff --git a/third_party/SPIRV-Tools/source/enum_set.h b/third_party/SPIRV-Tools/source/enum_set.h
index 28ee5fee8..a3751388a 100644
--- a/third_party/SPIRV-Tools/source/enum_set.h
+++ b/third_party/SPIRV-Tools/source/enum_set.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016 Google Inc.
+// Copyright (c) 2023 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,195 +12,456 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef SOURCE_ENUM_SET_H_
-#define SOURCE_ENUM_SET_H_
-
+#include <algorithm>
+#include <cassert>
#include <cstdint>
#include <functional>
-#include <memory>
-#include <set>
-#include <utility>
+#include <initializer_list>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+#ifndef SOURCE_ENUM_SET_H_
+#define SOURCE_ENUM_SET_H_
#include "source/latest_version_spirv_header.h"
-#include "source/util/make_unique.h"
namespace spvtools {
-// A set of values of a 32-bit enum type.
-// It is fast and compact for the common case, where enum values
-// are at most 63. But it can represent enums with larger values,
-// as may appear in extensions.
-template <typename EnumType>
+// This container is optimized to store and retrieve unsigned enum values.
+// The base model for this implementation is an open-addressing hashtable with
+// linear probing. For small enums (max index < 64), all operations are O(1).
+//
+// - Enums are stored in buckets (64 contiguous values max per bucket)
+// - Buckets ranges don't overlap, but don't have to be contiguous.
+// - Enums are packed into 64-bits buckets, using 1 bit per enum value.
+//
+// Example:
+// - MyEnum { A = 0, B = 1, C = 64, D = 65 }
+// - 2 buckets are required:
+// - bucket 0, storing values in the range [ 0; 64[
+// - bucket 1, storing values in the range [64; 128[
+//
+// - Buckets are stored in a sorted vector (sorted by bucket range).
+// - Retrieval is done by computing the theoretical bucket index using the enum
+// value, and
+// doing a linear scan from this position.
+// - Insertion is done by retrieving the bucket and either:
+// - inserting a new bucket in the sorted vector when no buckets has a
+// compatible range.
+// - setting the corresponding bit in the bucket.
+// This means insertion in the middle/beginning can cause a memmove when no
+// bucket is available. In our case, this happens at most 23 times for the
+// largest enum we have (Opcodes).
+template <typename T>
class EnumSet {
private:
- // The ForEach method will call the functor on enum values in
- // enum value order (lowest to highest). To make that easier, use
- // an ordered set for the overflow values.
- using OverflowSetType = std::set<uint32_t>;
+ using BucketType = uint64_t;
+ using ElementType = std::underlying_type_t<T>;
+ static_assert(std::is_enum_v<T>, "EnumSets only works with enums.");
+ static_assert(std::is_signed_v<ElementType> == false,
+ "EnumSet doesn't supports signed enums.");
+
+ // Each bucket can hold up to `kBucketSize` distinct, contiguous enum values.
+ // The first value a bucket can hold must be aligned on `kBucketSize`.
+ struct Bucket {
+ // bit mask to store `kBucketSize` enums.
+ BucketType data;
+ // 1st enum this bucket can represent.
+ T start;
+
+ friend bool operator==(const Bucket& lhs, const Bucket& rhs) {
+ return lhs.start == rhs.start && lhs.data == rhs.data;
+ }
+ };
+
+ // How many distinct values can a bucket hold? 1 bit per value.
+ static constexpr size_t kBucketSize = sizeof(BucketType) * 8ULL;
public:
- // Construct an empty set.
- EnumSet() {}
- // Construct an set with just the given enum value.
- explicit EnumSet(EnumType c) { Add(c); }
- // Construct an set from an initializer list of enum values.
- EnumSet(std::initializer_list<EnumType> cs) {
- for (auto c : cs) Add(c);
- }
- EnumSet(uint32_t count, const EnumType* ptr) {
- for (uint32_t i = 0; i < count; ++i) Add(ptr[i]);
- }
- // Copy constructor.
- EnumSet(const EnumSet& other) { *this = other; }
- // Move constructor. The moved-from set is emptied.
- EnumSet(EnumSet&& other) {
- mask_ = other.mask_;
- overflow_ = std::move(other.overflow_);
- other.mask_ = 0;
- other.overflow_.reset(nullptr);
- }
- // Assignment operator.
- EnumSet& operator=(const EnumSet& other) {
- if (&other != this) {
- mask_ = other.mask_;
- overflow_.reset(other.overflow_ ? new OverflowSetType(*other.overflow_)
- : nullptr);
+ class Iterator {
+ public:
+ typedef Iterator self_type;
+ typedef T value_type;
+ typedef T& reference;
+ typedef T* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef size_t difference_type;
+
+ Iterator(const Iterator& other)
+ : set_(other.set_),
+ bucketIndex_(other.bucketIndex_),
+ bucketOffset_(other.bucketOffset_) {}
+
+ Iterator& operator++() {
+ do {
+ if (bucketIndex_ >= set_->buckets_.size()) {
+ bucketIndex_ = set_->buckets_.size();
+ bucketOffset_ = 0;
+ break;
+ }
+
+ if (bucketOffset_ + 1 == kBucketSize) {
+ bucketOffset_ = 0;
+ ++bucketIndex_;
+ } else {
+ ++bucketOffset_;
+ }
+
+ } while (bucketIndex_ < set_->buckets_.size() &&
+ !set_->HasEnumAt(bucketIndex_, bucketOffset_));
+ return *this;
}
- return *this;
- }
- friend bool operator==(const EnumSet& a, const EnumSet& b) {
- if (a.mask_ != b.mask_) {
- return false;
+ Iterator operator++(int) {
+ Iterator old = *this;
+ operator++();
+ return old;
}
- if (a.overflow_ == nullptr && b.overflow_ == nullptr) {
- return true;
+ T operator*() const {
+ assert(set_->HasEnumAt(bucketIndex_, bucketOffset_) &&
+ "operator*() called on an invalid iterator.");
+ return GetValueFromBucket(set_->buckets_[bucketIndex_], bucketOffset_);
}
- if (a.overflow_ == nullptr || b.overflow_ == nullptr) {
- return false;
+ bool operator!=(const Iterator& other) const {
+ return set_ != other.set_ || bucketOffset_ != other.bucketOffset_ ||
+ bucketIndex_ != other.bucketIndex_;
}
- return *a.overflow_ == *b.overflow_;
+ bool operator==(const Iterator& other) const {
+ return !(operator!=(other));
+ }
+
+ Iterator& operator=(const Iterator& other) {
+ set_ = other.set_;
+ bucketIndex_ = other.bucketIndex_;
+ bucketOffset_ = other.bucketOffset_;
+ return *this;
+ }
+
+ private:
+ Iterator(const EnumSet* set, size_t bucketIndex, ElementType bucketOffset)
+ : set_(set), bucketIndex_(bucketIndex), bucketOffset_(bucketOffset) {}
+
+ private:
+ const EnumSet* set_ = nullptr;
+ // Index of the bucket in the vector.
+ size_t bucketIndex_ = 0;
+ // Offset in bits in the current bucket.
+ ElementType bucketOffset_ = 0;
+
+ friend class EnumSet;
+ };
+
+ // Required to allow the use of std::inserter.
+ using value_type = T;
+ using const_iterator = Iterator;
+ using iterator = Iterator;
+
+ public:
+ iterator cbegin() const noexcept {
+ auto it = iterator(this, /* bucketIndex= */ 0, /* bucketOffset= */ 0);
+ if (buckets_.size() == 0) {
+ return it;
+ }
+
+ // The iterator has the logic to find the next valid bit. If the value 0
+ // is not stored, use it to find the next valid bit.
+ if (!HasEnumAt(it.bucketIndex_, it.bucketOffset_)) {
+ ++it;
+ }
+
+ return it;
}
- friend bool operator!=(const EnumSet& a, const EnumSet& b) {
- return !(a == b);
+ iterator begin() const noexcept { return cbegin(); }
+
+ iterator cend() const noexcept {
+ return iterator(this, buckets_.size(), /* bucketOffset= */ 0);
}
- // Adds the given enum value to the set. This has no effect if the
- // enum value is already in the set.
- void Add(EnumType c) { AddWord(ToWord(c)); }
+ iterator end() const noexcept { return cend(); }
- // Removes the given enum value from the set. This has no effect if the
- // enum value is not in the set.
- void Remove(EnumType c) { RemoveWord(ToWord(c)); }
+ // Creates an empty set.
+ EnumSet() : buckets_(0), size_(0) {}
- // Returns true if this enum value is in the set.
- bool Contains(EnumType c) const { return ContainsWord(ToWord(c)); }
+ // Creates a set and store `value` in it.
+ EnumSet(T value) : EnumSet() { insert(value); }
- // Applies f to each enum in the set, in order from smallest enum
- // value to largest.
- void ForEach(std::function<void(EnumType)> f) const {
- for (uint32_t i = 0; i < 64; ++i) {
- if (mask_ & AsMask(i)) f(static_cast<EnumType>(i));
+ // Creates a set and stores each `values` in it.
+ EnumSet(std::initializer_list<T> values) : EnumSet() {
+ for (auto item : values) {
+ insert(item);
}
- if (overflow_) {
- for (uint32_t c : *overflow_) f(static_cast<EnumType>(c));
+ }
+
+ // Creates a set, and insert `count` enum values pointed by `array` in it.
+ EnumSet(ElementType count, const T* array) : EnumSet() {
+ for (ElementType i = 0; i < count; i++) {
+ insert(array[i]);
}
}
- // Returns true if the set is empty.
- bool IsEmpty() const {
- if (mask_) return false;
- if (overflow_ && !overflow_->empty()) return false;
- return true;
+ // Creates a set initialized with the content of the range [begin; end[.
+ template <class InputIt>
+ EnumSet(InputIt begin, InputIt end) : EnumSet() {
+ for (; begin != end; ++begin) {
+ insert(*begin);
+ }
}
- // Returns true if the set contains ANY of the elements of |in_set|,
- // or if |in_set| is empty.
- bool HasAnyOf(const EnumSet<EnumType>& in_set) const {
- if (in_set.IsEmpty()) return true;
+ // Copies the EnumSet `other` into a new EnumSet.
+ EnumSet(const EnumSet& other)
+ : buckets_(other.buckets_), size_(other.size_) {}
- if (mask_ & in_set.mask_) return true;
+ // Moves the EnumSet `other` into a new EnumSet.
+ EnumSet(EnumSet&& other)
+ : buckets_(std::move(other.buckets_)), size_(other.size_) {}
- if (!overflow_ || !in_set.overflow_) return false;
+ // Deep-copies the EnumSet `other` into this EnumSet.
+ EnumSet& operator=(const EnumSet& other) {
+ buckets_ = other.buckets_;
+ size_ = other.size_;
+ return *this;
+ }
+
+ // Matches std::unordered_set::insert behavior.
+ std::pair<iterator, bool> insert(const T& value) {
+ const size_t index = FindBucketForValue(value);
+ const ElementType offset = ComputeBucketOffset(value);
- for (uint32_t item : *in_set.overflow_) {
- if (overflow_->find(item) != overflow_->end()) return true;
+ if (index >= buckets_.size() ||
+ buckets_[index].start != ComputeBucketStart(value)) {
+ size_ += 1;
+ InsertBucketFor(index, value);
+ return std::make_pair(Iterator(this, index, offset), true);
}
- return false;
+ auto& bucket = buckets_[index];
+ const auto mask = ComputeMaskForValue(value);
+ if (bucket.data & mask) {
+ return std::make_pair(Iterator(this, index, offset), false);
+ }
+
+ size_ += 1;
+ bucket.data |= ComputeMaskForValue(value);
+ return std::make_pair(Iterator(this, index, offset), true);
}
- private:
- // Adds the given enum value (as a 32-bit word) to the set. This has no
- // effect if the enum value is already in the set.
- void AddWord(uint32_t word) {
- if (auto new_bits = AsMask(word)) {
- mask_ |= new_bits;
- } else {
- Overflow().insert(word);
+ // Inserts `value` in the set if possible.
+ // Similar to `std::unordered_set::insert`, except the hint is ignored.
+ // Returns an iterator to the inserted element, or the element preventing
+ // insertion.
+ iterator insert(const_iterator, const T& value) {
+ return insert(value).first;
+ }
+
+ // Inserts `value` in the set if possible.
+ // Similar to `std::unordered_set::insert`, except the hint is ignored.
+ // Returns an iterator to the inserted element, or the element preventing
+ // insertion.
+ iterator insert(const_iterator, T&& value) { return insert(value).first; }
+
+ // Inserts all the values in the range [`first`; `last[.
+ // Similar to `std::unordered_set::insert`.
+ template <class InputIt>
+ void insert(InputIt first, InputIt last) {
+ for (auto it = first; it != last; ++it) {
+ insert(*it);
+ }
+ }
+
+ // Removes the value `value` into the set.
+ // Similar to `std::unordered_set::erase`.
+ // Returns the number of erased elements.
+ size_t erase(const T& value) {
+ const size_t index = FindBucketForValue(value);
+ if (index >= buckets_.size() ||
+ buckets_[index].start != ComputeBucketStart(value)) {
+ return 0;
+ }
+
+ auto& bucket = buckets_[index];
+ const auto mask = ComputeMaskForValue(value);
+ if (!(bucket.data & mask)) {
+ return 0;
}
+
+ size_ -= 1;
+ bucket.data &= ~mask;
+ if (bucket.data == 0) {
+ buckets_.erase(buckets_.cbegin() + index);
+ }
+ return 1;
}
- // Removes the given enum value (as a 32-bit word) from the set. This has no
- // effect if the enum value is not in the set.
- void RemoveWord(uint32_t word) {
- if (auto new_bits = AsMask(word)) {
- mask_ &= ~new_bits;
- } else {
- auto itr = Overflow().find(word);
- if (itr != Overflow().end()) Overflow().erase(itr);
+ // Returns true if `value` is present in the set.
+ bool contains(T value) const {
+ const size_t index = FindBucketForValue(value);
+ if (index >= buckets_.size() ||
+ buckets_[index].start != ComputeBucketStart(value)) {
+ return false;
}
+ auto& bucket = buckets_[index];
+ return bucket.data & ComputeMaskForValue(value);
}
- // Returns true if the enum represented as a 32-bit word is in the set.
- bool ContainsWord(uint32_t word) const {
- // We shouldn't call Overflow() since this is a const method.
- if (auto bits = AsMask(word)) {
- return (mask_ & bits) != 0;
- } else if (auto overflow = overflow_.get()) {
- return overflow->find(word) != overflow->end();
+ // Returns the 1 if `value` is present in the set, `0` otherwise.
+ inline size_t count(T value) const { return contains(value) ? 1 : 0; }
+
+ // Returns true if the set is holds no values.
+ inline bool empty() const { return size_ == 0; }
+
+ // Returns the number of enums stored in this set.
+ size_t size() const { return size_; }
+
+ // Returns true if this set contains at least one value contained in `in_set`.
+ // Note: If `in_set` is empty, this function returns true.
+ bool HasAnyOf(const EnumSet<T>& in_set) const {
+ if (in_set.empty()) {
+ return true;
+ }
+
+ auto lhs = buckets_.cbegin();
+ auto rhs = in_set.buckets_.cbegin();
+
+ while (lhs != buckets_.cend() && rhs != in_set.buckets_.cend()) {
+ if (lhs->start == rhs->start) {
+ if (lhs->data & rhs->data) {
+ // At least 1 bit is shared. Early return.
+ return true;
+ }
+
+ lhs++;
+ rhs++;
+ continue;
+ }
+
+ // LHS bucket is smaller than the current RHS bucket. Catching up on RHS.
+ if (lhs->start < rhs->start) {
+ lhs++;
+ continue;
+ }
+
+ // Otherwise, RHS needs to catch up on LHS.
+ rhs++;
}
- // The word is large, but the set doesn't have large members, so
- // it doesn't have an overflow set.
+
return false;
}
- // Returns the enum value as a uint32_t.
- uint32_t ToWord(EnumType value) const {
- static_assert(sizeof(EnumType) <= sizeof(uint32_t),
- "EnumType must statically castable to uint32_t");
- return static_cast<uint32_t>(value);
+ private:
+ // Returns the index of the last bucket in which `value` could be stored.
+ static constexpr inline size_t ComputeLargestPossibleBucketIndexFor(T value) {
+ return static_cast<size_t>(value) / kBucketSize;
}
- // Determines whether the given enum value can be represented
- // as a bit in a uint64_t mask. If so, then returns that mask bit.
- // Otherwise, returns 0.
- uint64_t AsMask(uint32_t word) const {
- if (word > 63) return 0;
- return uint64_t(1) << word;
+ // Returns the smallest enum value that could be contained in the same bucket
+ // as `value`.
+ static constexpr inline T ComputeBucketStart(T value) {
+ return static_cast<T>(kBucketSize *
+ ComputeLargestPossibleBucketIndexFor(value));
}
- // Ensures that overflow_set_ references a set. A new empty set is
- // allocated if one doesn't exist yet. Returns overflow_set_.
- OverflowSetType& Overflow() {
- if (overflow_.get() == nullptr) {
- overflow_ = MakeUnique<OverflowSetType>();
+ // Returns the index of the bit that corresponds to `value` in the bucket.
+ static constexpr inline ElementType ComputeBucketOffset(T value) {
+ return static_cast<ElementType>(value) % kBucketSize;
+ }
+
+ // Returns the bitmask used to represent the enum `value` in its bucket.
+ static constexpr inline BucketType ComputeMaskForValue(T value) {
+ return 1ULL << ComputeBucketOffset(value);
+ }
+
+ // Returns the `enum` stored in `bucket` at `offset`.
+ // `offset` is the bit-offset in the bucket storage.
+ static constexpr inline T GetValueFromBucket(const Bucket& bucket,
+ BucketType offset) {
+ return static_cast<T>(static_cast<ElementType>(bucket.start) + offset);
+ }
+
+ // For a given enum `value`, finds the bucket index that could contain this
+ // value. If no such bucket is found, the index at which the new bucket should
+ // be inserted is returned.
+ size_t FindBucketForValue(T value) const {
+ // Set is empty, insert at 0.
+ if (buckets_.size() == 0) {
+ return 0;
}
- return *overflow_;
+
+ const T wanted_start = ComputeBucketStart(value);
+ assert(buckets_.size() > 0 &&
+ "Size must not be 0 here. Has the code above changed?");
+ size_t index = std::min(buckets_.size() - 1,
+ ComputeLargestPossibleBucketIndexFor(value));
+
+ // This loops behaves like std::upper_bound with a reverse iterator.
+ // Buckets are sorted. 3 main cases:
+ // - The bucket matches
+ // => returns the bucket index.
+ // - The found bucket is larger
+ // => scans left until it finds the correct bucket, or insertion point.
+ // - The found bucket is smaller
+ // => We are at the end, so we return past-end index for insertion.
+ for (; buckets_[index].start >= wanted_start; index--) {
+ if (index == 0) {
+ return 0;
+ }
+ }
+
+ return index + 1;
+ }
+
+ // Creates a new bucket to store `value` and inserts it at `index`.
+ // If the `index` is past the end, the bucket is inserted at the end of the
+ // vector.
+ void InsertBucketFor(size_t index, T value) {
+ const T bucket_start = ComputeBucketStart(value);
+ Bucket bucket = {1ULL << ComputeBucketOffset(value), bucket_start};
+ auto it = buckets_.emplace(buckets_.begin() + index, std::move(bucket));
+#if defined(NDEBUG)
+ (void)it; // Silencing unused variable warning.
+#else
+ assert(std::next(it) == buckets_.end() ||
+ std::next(it)->start > bucket_start);
+ assert(it == buckets_.begin() || std::prev(it)->start < bucket_start);
+#endif
+ }
+
+ // Returns true if the bucket at `bucketIndex/ stores the enum at
+ // `bucketOffset`, false otherwise.
+ bool HasEnumAt(size_t bucketIndex, BucketType bucketOffset) const {
+ assert(bucketIndex < buckets_.size());
+ assert(bucketOffset < kBucketSize);
+ return buckets_[bucketIndex].data & (1ULL << bucketOffset);
+ }
+
+ // Returns true if `lhs` and `rhs` hold the exact same values.
+ friend bool operator==(const EnumSet& lhs, const EnumSet& rhs) {
+ if (lhs.size_ != rhs.size_) {
+ return false;
+ }
+
+ if (lhs.buckets_.size() != rhs.buckets_.size()) {
+ return false;
+ }
+ return lhs.buckets_ == rhs.buckets_;
+ }
+
+ // Returns true if `lhs` and `rhs` hold at least 1 different value.
+ friend bool operator!=(const EnumSet& lhs, const EnumSet& rhs) {
+ return !(lhs == rhs);
}
- // Enums with values up to 63 are stored as bits in this mask.
- uint64_t mask_ = 0;
- // Enums with values larger than 63 are stored in this set.
- // This set should normally be empty or very small.
- std::unique_ptr<OverflowSetType> overflow_ = {};
+ // Storage for the buckets.
+ std::vector<Bucket> buckets_;
+ // How many enums is this set storing.
+ size_t size_ = 0;
};
-// A set of spv::Capability, optimized for small capability values.
+// A set of spv::Capability.
using CapabilitySet = EnumSet<spv::Capability>;
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/ext_inst.cpp b/third_party/SPIRV-Tools/source/ext_inst.cpp
index 4e2795453..9a5ba84e4 100644
--- a/third_party/SPIRV-Tools/source/ext_inst.cpp
+++ b/third_party/SPIRV-Tools/source/ext_inst.cpp
@@ -30,6 +30,7 @@
#include "glsl.std.450.insts.inc"
#include "nonsemantic.clspvreflection.insts.inc"
#include "nonsemantic.shader.debuginfo.100.insts.inc"
+#include "nonsemantic.vkspreflection.insts.inc"
#include "opencl.debuginfo.100.insts.inc"
#include "opencl.std.insts.inc"
@@ -62,6 +63,9 @@ static const spv_ext_inst_group_t kGroups_1_0[] = {
{SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
ARRAY_SIZE(nonsemantic_clspvreflection_entries),
nonsemantic_clspvreflection_entries},
+ {SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION,
+ ARRAY_SIZE(nonsemantic_vkspreflection_entries),
+ nonsemantic_vkspreflection_entries},
};
static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0),
@@ -138,6 +142,9 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) {
if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) {
return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION;
}
+ if (!strncmp("NonSemantic.VkspReflection.", name, 27)) {
+ return SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION;
+ }
// ensure to add any known non-semantic extended instruction sets
// above this point, and update spvExtInstIsNonSemantic()
if (!strncmp("NonSemantic.", name, 12)) {
@@ -149,7 +156,8 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) {
bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) {
if (type == SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN ||
type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
- type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
+ type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION ||
+ type == SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION) {
return true;
}
return false;
diff --git a/third_party/SPIRV-Tools/source/extensions.cpp b/third_party/SPIRV-Tools/source/extensions.cpp
index ebf6bec06..ac987fcc0 100644
--- a/third_party/SPIRV-Tools/source/extensions.cpp
+++ b/third_party/SPIRV-Tools/source/extensions.cpp
@@ -40,8 +40,9 @@ std::string GetExtensionString(const spv_parsed_instruction_t* inst) {
std::string ExtensionSetToString(const ExtensionSet& extensions) {
std::stringstream ss;
- extensions.ForEach(
- [&ss](Extension ext) { ss << ExtensionToString(ext) << " "; });
+ for (auto extension : extensions) {
+ ss << ExtensionToString(extension) << " ";
+ }
return ss.str();
}
diff --git a/third_party/SPIRV-Tools/source/extensions.h b/third_party/SPIRV-Tools/source/extensions.h
index 8023444c3..cda4924a4 100644
--- a/third_party/SPIRV-Tools/source/extensions.h
+++ b/third_party/SPIRV-Tools/source/extensions.h
@@ -15,6 +15,7 @@
#ifndef SOURCE_EXTENSIONS_H_
#define SOURCE_EXTENSIONS_H_
+#include <cstdint>
#include <string>
#include "source/enum_set.h"
@@ -23,7 +24,7 @@
namespace spvtools {
// The known SPIR-V extensions.
-enum Extension {
+enum Extension : uint32_t {
#include "extension_enum.inc"
};
diff --git a/third_party/SPIRV-Tools/source/fuzz/transformation_add_no_contraction_decoration.cpp b/third_party/SPIRV-Tools/source/fuzz/transformation_add_no_contraction_decoration.cpp
index 07a31e5cb..87393e95b 100644
--- a/third_party/SPIRV-Tools/source/fuzz/transformation_add_no_contraction_decoration.cpp
+++ b/third_party/SPIRV-Tools/source/fuzz/transformation_add_no_contraction_decoration.cpp
@@ -36,6 +36,11 @@ bool TransformationAddNoContractionDecoration::IsApplicable(
if (!instr) {
return false;
}
+ // |instr| must not be decorated with NoContraction.
+ if (ir_context->get_decoration_mgr()->HasDecoration(
+ message_.result_id(), spv::Decoration::NoContraction)) {
+ return false;
+ }
// The instruction must be arithmetic.
return IsArithmetic(instr->opcode());
}
diff --git a/third_party/SPIRV-Tools/source/fuzz/transformation_add_relaxed_decoration.cpp b/third_party/SPIRV-Tools/source/fuzz/transformation_add_relaxed_decoration.cpp
index 6cd4ecbb3..601546c97 100644
--- a/third_party/SPIRV-Tools/source/fuzz/transformation_add_relaxed_decoration.cpp
+++ b/third_party/SPIRV-Tools/source/fuzz/transformation_add_relaxed_decoration.cpp
@@ -36,6 +36,11 @@ bool TransformationAddRelaxedDecoration::IsApplicable(
if (!instr) {
return false;
}
+ // |instr| must not be decorated with RelaxedPrecision.
+ if (ir_context->get_decoration_mgr()->HasDecoration(
+ message_.result_id(), spv::Decoration::RelaxedPrecision)) {
+ return false;
+ }
opt::BasicBlock* cur_block = ir_context->get_instr_block(instr);
// The instruction must have a block.
if (cur_block == nullptr) {
@@ -46,6 +51,7 @@ bool TransformationAddRelaxedDecoration::IsApplicable(
cur_block->id()))) {
return false;
}
+
// The instruction must be numeric.
return IsNumeric(instr->opcode());
}
diff --git a/third_party/SPIRV-Tools/source/link/linker.cpp b/third_party/SPIRV-Tools/source/link/linker.cpp
index e50391a1b..58930e452 100644
--- a/third_party/SPIRV-Tools/source/link/linker.cpp
+++ b/third_party/SPIRV-Tools/source/link/linker.cpp
@@ -91,7 +91,8 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
// should be non-null. |max_id_bound| should be strictly greater than 0.
spv_result_t GenerateHeader(const MessageConsumer& consumer,
const std::vector<opt::Module*>& modules,
- uint32_t max_id_bound, opt::ModuleHeader* header);
+ uint32_t max_id_bound, opt::ModuleHeader* header,
+ const LinkerOptions& options);
// Merge all the modules from |in_modules| into a single module owned by
// |linked_context|.
@@ -202,7 +203,8 @@ spv_result_t ShiftIdsInModules(const MessageConsumer& consumer,
spv_result_t GenerateHeader(const MessageConsumer& consumer,
const std::vector<opt::Module*>& modules,
- uint32_t max_id_bound, opt::ModuleHeader* header) {
+ uint32_t max_id_bound, opt::ModuleHeader* header,
+ const LinkerOptions& options) {
spv_position_t position = {};
if (modules.empty())
@@ -212,10 +214,12 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer,
return DiagnosticStream(position, consumer, "", SPV_ERROR_INVALID_DATA)
<< "|max_id_bound| of GenerateHeader should not be null.";
- const uint32_t linked_version = modules.front()->version();
+ uint32_t linked_version = modules.front()->version();
for (std::size_t i = 1; i < modules.size(); ++i) {
const uint32_t module_version = modules[i]->version();
- if (module_version != linked_version)
+ if (options.GetUseHighestVersion()) {
+ linked_version = std::max(linked_version, module_version);
+ } else if (module_version != linked_version) {
return DiagnosticStream({0, 0, 1}, consumer, "", SPV_ERROR_INTERNAL)
<< "Conflicting SPIR-V versions: "
<< SPV_SPIRV_VERSION_MAJOR_PART(linked_version) << "."
@@ -224,6 +228,7 @@ spv_result_t GenerateHeader(const MessageConsumer& consumer,
<< SPV_SPIRV_VERSION_MAJOR_PART(module_version) << "."
<< SPV_SPIRV_VERSION_MINOR_PART(module_version)
<< " (input module " << (i + 1) << ").";
+ }
}
header->magic_number = spv::MagicNumber;
@@ -753,7 +758,7 @@ spv_result_t Link(const Context& context, const uint32_t* const* binaries,
// Phase 2: Generate the header
opt::ModuleHeader header;
- res = GenerateHeader(consumer, modules, max_id_bound, &header);
+ res = GenerateHeader(consumer, modules, max_id_bound, &header, options);
if (res != SPV_SUCCESS) return res;
IRContext linked_context(c_context->target_env, consumer);
linked_context.module()->SetHeader(header);
diff --git a/third_party/SPIRV-Tools/source/opcode.cpp b/third_party/SPIRV-Tools/source/opcode.cpp
index d26024abb..787dbb340 100644
--- a/third_party/SPIRV-Tools/source/opcode.cpp
+++ b/third_party/SPIRV-Tools/source/opcode.cpp
@@ -274,6 +274,7 @@ int32_t spvOpcodeIsComposite(const spv::Op opcode) {
case spv::Op::OpTypeArray:
case spv::Op::OpTypeStruct:
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
return true;
default:
return false;
@@ -294,6 +295,7 @@ bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) {
case spv::Op::OpPtrAccessChain:
case spv::Op::OpLoad:
case spv::Op::OpConstantNull:
+ case spv::Op::OpRawAccessChainNV:
return true;
default:
return false;
@@ -308,6 +310,7 @@ int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
case spv::Op::OpFunctionParameter:
case spv::Op::OpImageTexelPointer:
case spv::Op::OpCopyObject:
+ case spv::Op::OpRawAccessChainNV:
return true;
default:
return false;
@@ -340,6 +343,7 @@ int32_t spvOpcodeGeneratesType(spv::Op op) {
case spv::Op::OpTypeNamedBarrier:
case spv::Op::OpTypeAccelerationStructureNV:
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
// case spv::Op::OpTypeAccelerationStructureKHR: covered by
// spv::Op::OpTypeAccelerationStructureNV
case spv::Op::OpTypeRayQueryKHR:
@@ -532,6 +536,8 @@ bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) {
case spv::Op::OpGroupNonUniformQuadBroadcast:
case spv::Op::OpGroupNonUniformQuadSwap:
case spv::Op::OpGroupNonUniformRotateKHR:
+ case spv::Op::OpGroupNonUniformQuadAllKHR:
+ case spv::Op::OpGroupNonUniformQuadAnyKHR:
return true;
default:
return false;
@@ -750,6 +756,7 @@ bool spvOpcodeIsAccessChain(spv::Op opcode) {
case spv::Op::OpInBoundsAccessChain:
case spv::Op::OpPtrAccessChain:
case spv::Op::OpInBoundsPtrAccessChain:
+ case spv::Op::OpRawAccessChainNV:
return true;
default:
return false;
diff --git a/third_party/SPIRV-Tools/source/operand.cpp b/third_party/SPIRV-Tools/source/operand.cpp
index 31a6c5965..784884674 100644
--- a/third_party/SPIRV-Tools/source/operand.cpp
+++ b/third_party/SPIRV-Tools/source/operand.cpp
@@ -26,7 +26,6 @@
#include "source/macro.h"
#include "source/opcode.h"
#include "source/spirv_constant.h"
-#include "source/spirv_target_env.h"
// For now, assume unified1 contains up to SPIR-V 1.3 and no later
// SPIR-V version.
@@ -48,7 +47,7 @@ spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
return SPV_SUCCESS;
}
-spv_result_t spvOperandTableNameLookup(spv_target_env env,
+spv_result_t spvOperandTableNameLookup(spv_target_env,
const spv_operand_table table,
const spv_operand_type_t type,
const char* name,
@@ -57,31 +56,18 @@ spv_result_t spvOperandTableNameLookup(spv_target_env env,
if (!table) return SPV_ERROR_INVALID_TABLE;
if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
- const auto version = spvVersionForTargetEnv(env);
for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
const auto& group = table->types[typeIndex];
if (type != group.type) continue;
for (uint64_t index = 0; index < group.count; ++index) {
const auto& entry = group.entries[index];
// We consider the current operand as available as long as
- // 1. The target environment satisfies the minimal requirement of the
- // operand; or
- // 2. There is at least one extension enabling this operand; or
- // 3. There is at least one capability enabling this operand.
- //
- // Note that the second rule assumes the extension enabling this operand
- // is indeed requested in the SPIR-V code; checking that should be
- // validator's work.
+ // it is in the grammar. It might not be *valid* to use,
+ // but that should be checked by the validator, not by parsing.
if (nameLength == strlen(entry.name) &&
!strncmp(entry.name, name, nameLength)) {
- if ((version >= entry.minVersion && version <= entry.lastVersion) ||
- entry.numExtensions > 0u || entry.numCapabilities > 0u) {
- *pEntry = &entry;
- return SPV_SUCCESS;
- } else {
- // if there is no extension/capability then the version is wrong
- return SPV_ERROR_WRONG_VERSION;
- }
+ *pEntry = &entry;
+ return SPV_SUCCESS;
}
}
}
@@ -89,7 +75,7 @@ spv_result_t spvOperandTableNameLookup(spv_target_env env,
return SPV_ERROR_INVALID_LOOKUP;
}
-spv_result_t spvOperandTableValueLookup(spv_target_env env,
+spv_result_t spvOperandTableValueLookup(spv_target_env,
const spv_operand_table table,
const spv_operand_type_t type,
const uint32_t value,
@@ -110,33 +96,15 @@ spv_result_t spvOperandTableValueLookup(spv_target_env env,
const auto beg = group.entries;
const auto end = group.entries + group.count;
- // We need to loop here because there can exist multiple symbols for the
- // same operand value, and they can be introduced in different target
- // environments, which means they can have different minimal version
- // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
- // version as long as the SPV_KHR_shader_ballot extension is there; but
- // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
- // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
- // requirements.
// Assumes the underlying table is already sorted ascendingly according to
// opcode value.
- const auto version = spvVersionForTargetEnv(env);
- for (auto it = std::lower_bound(beg, end, needle, comp);
- it != end && it->value == value; ++it) {
- // We consider the current operand as available as long as
- // 1. The target environment satisfies the minimal requirement of the
- // operand; or
- // 2. There is at least one extension enabling this operand; or
- // 3. There is at least one capability enabling this operand.
- //
- // Note that the second rule assumes the extension enabling this operand
- // is indeed requested in the SPIR-V code; checking that should be
- // validator's work.
- if ((version >= it->minVersion && version <= it->lastVersion) ||
- it->numExtensions > 0u || it->numCapabilities > 0u) {
- *pEntry = it;
- return SPV_SUCCESS;
- }
+ auto it = std::lower_bound(beg, end, needle, comp);
+ if (it != end && it->value == value) {
+ // The current operand is considered available as long as
+ // it is in the grammar. It might not be *valid* to use,
+ // but that should be checked by the validator, not by parsing.
+ *pEntry = it;
+ return SPV_SUCCESS;
}
}
@@ -155,6 +123,7 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_LITERAL_INTEGER:
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT:
return "literal number";
case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
return "possibly multi-word literal integer";
@@ -236,6 +205,26 @@ const char* spvOperandTypeStr(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
return "packed vector format";
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
+ case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
+ return "cooperative matrix operands";
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
+ return "cooperative matrix layout";
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
+ return "cooperative matrix use";
+ case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
+ return "initialization mode qualifier";
+ case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
+ return "host access qualifier";
+ case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
+ return "load cache control";
+ case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
+ return "store cache control";
+ case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
+ return "named maximum number of registers";
+ case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
+ case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
+ return "raw access chain operands";
case SPV_OPERAND_TYPE_IMAGE:
case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
return "image";
@@ -325,6 +314,7 @@ bool spvOperandIsConcrete(spv_operand_type_t type) {
}
switch (type) {
case SPV_OPERAND_TYPE_LITERAL_INTEGER:
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT:
case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
@@ -369,6 +359,13 @@ bool spvOperandIsConcrete(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
case SPV_OPERAND_TYPE_OVERFLOW_MODES:
case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT:
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_USE:
+ case SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER:
+ case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER:
+ case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL:
+ case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL:
+ case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS:
return true;
default:
break;
@@ -387,6 +384,8 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
+ case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS:
+ case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS:
return true;
default:
break;
@@ -405,7 +404,9 @@ bool spvOperandIsOptional(spv_operand_type_t type) {
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
+ case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS:
case SPV_OPERAND_TYPE_OPTIONAL_CIV:
+ case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
return true;
default:
break;
diff --git a/third_party/SPIRV-Tools/source/operand.h b/third_party/SPIRV-Tools/source/operand.h
index a3010d934..f74c93389 100644
--- a/third_party/SPIRV-Tools/source/operand.h
+++ b/third_party/SPIRV-Tools/source/operand.h
@@ -57,12 +57,6 @@ spv_result_t spvOperandTableValueLookup(spv_target_env,
// Gets the name string of the non-variable operand type.
const char* spvOperandTypeStr(spv_operand_type_t type);
-// Returns true if the given type is concrete.
-bool spvOperandIsConcrete(spv_operand_type_t type);
-
-// Returns true if the given type is concrete and also a mask.
-bool spvOperandIsConcreteMask(spv_operand_type_t type);
-
// Returns true if an operand of the given type is optional.
bool spvOperandIsOptional(spv_operand_type_t type);
diff --git a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
index eea3c4753..4e7d92d5e 100644
--- a/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/source/opt/CMakeLists.txt
@@ -71,6 +71,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
instruction_list.h
instrument_pass.h
interface_var_sroa.h
+ invocation_interlock_placement_pass.h
interp_fixup_pass.h
ir_builder.h
ir_context.h
@@ -93,6 +94,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
loop_unswitch_pass.h
mem_pass.h
merge_return_pass.h
+ modify_maximal_reconvergence.h
module.h
null_pass.h
passes.h
@@ -121,7 +123,9 @@ set(SPIRV_TOOLS_OPT_SOURCES
strip_debug_info_pass.h
strip_nonsemantic_info_pass.h
struct_cfg_analysis.h
+ switch_descriptorset_pass.h
tree_iterator.h
+ trim_capabilities_pass.h
type_manager.h
types.h
unify_const_pass.h
@@ -189,6 +193,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
instruction_list.cpp
instrument_pass.cpp
interface_var_sroa.cpp
+ invocation_interlock_placement_pass.cpp
interp_fixup_pass.cpp
ir_context.cpp
ir_loader.cpp
@@ -210,6 +215,7 @@ set(SPIRV_TOOLS_OPT_SOURCES
loop_unswitch_pass.cpp
mem_pass.cpp
merge_return_pass.cpp
+ modify_maximal_reconvergence.cpp
module.cpp
optimizer.cpp
pass.cpp
@@ -236,6 +242,8 @@ set(SPIRV_TOOLS_OPT_SOURCES
strip_debug_info_pass.cpp
strip_nonsemantic_info_pass.cpp
struct_cfg_analysis.cpp
+ switch_descriptorset_pass.cpp
+ trim_capabilities_pass.cpp
type_manager.cpp
types.cpp
unify_const_pass.cpp
diff --git a/third_party/SPIRV-Tools/source/opt/aggressive_dead_code_elim_pass.cpp b/third_party/SPIRV-Tools/source/opt/aggressive_dead_code_elim_pass.cpp
index 16456386b..4737da5f9 100644
--- a/third_party/SPIRV-Tools/source/opt/aggressive_dead_code_elim_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/aggressive_dead_code_elim_pass.cpp
@@ -438,6 +438,9 @@ std::vector<uint32_t> AggressiveDCEPass::GetLoadedVariablesFromFunctionCall(
const Instruction* inst) {
assert(inst->opcode() == spv::Op::OpFunctionCall);
std::vector<uint32_t> live_variables;
+ // NOTE: we should only be checking function call parameters here, not the
+ // function itself, however, `IsPtr` will trivially return false for
+ // OpFunction
inst->ForEachInId([this, &live_variables](const uint32_t* operand_id) {
if (!IsPtr(*operand_id)) return;
uint32_t var_id = GetVariableId(*operand_id);
@@ -938,6 +941,8 @@ Pass::Status AggressiveDCEPass::Process() {
void AggressiveDCEPass::InitExtensions() {
extensions_allowlist_.clear();
+
+ // clang-format off
extensions_allowlist_.insert({
"SPV_AMD_shader_explicit_vertex_parameter",
"SPV_AMD_shader_trinary_minmax",
@@ -980,11 +985,13 @@ void AggressiveDCEPass::InitExtensions() {
"SPV_NV_shader_image_footprint",
"SPV_NV_shading_rate",
"SPV_NV_mesh_shader",
+ "SPV_EXT_mesh_shader",
"SPV_NV_ray_tracing",
"SPV_KHR_ray_tracing",
"SPV_KHR_ray_query",
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_physical_storage_buffer",
+ "SPV_KHR_physical_storage_buffer",
"SPV_KHR_terminate_invocation",
"SPV_KHR_shader_clock",
"SPV_KHR_vulkan_memory_model",
@@ -994,7 +1001,12 @@ void AggressiveDCEPass::InitExtensions() {
"SPV_KHR_non_semantic_info",
"SPV_KHR_uniform_group_instructions",
"SPV_KHR_fragment_shader_barycentric",
+ "SPV_NV_bindless_texture",
+ "SPV_EXT_shader_atomic_float_add",
+ "SPV_EXT_fragment_shader_interlock",
+ "SPV_NV_compute_shader_derivatives"
});
+ // clang-format on
}
Instruction* AggressiveDCEPass::GetHeaderBranch(BasicBlock* blk) {
diff --git a/third_party/SPIRV-Tools/source/opt/block_merge_util.cpp b/third_party/SPIRV-Tools/source/opt/block_merge_util.cpp
index fe23e36f9..42f695f23 100644
--- a/third_party/SPIRV-Tools/source/opt/block_merge_util.cpp
+++ b/third_party/SPIRV-Tools/source/opt/block_merge_util.cpp
@@ -98,6 +98,17 @@ bool CanMergeWithSuccessor(IRContext* context, BasicBlock* block) {
return false;
}
+ // Note: This means that the instructions in a break block will execute as if
+ // they were still diverged according to the loop iteration. This restricts
+ // potential transformations an implementation may perform on the IR to match
+ // shader author expectations. Similarly, instructions in the loop construct
+ // cannot be moved into the continue construct unless it can be proven that
+ // invocations are always converged.
+ if (succ_is_merge && context->get_feature_mgr()->HasExtension(
+ kSPV_KHR_maximal_reconvergence)) {
+ return false;
+ }
+
if (pred_is_merge && IsContinue(context, lab_id)) {
// Cannot merge a continue target with a merge block.
return false;
diff --git a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
index 26108082f..17900af24 100644
--- a/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
+++ b/third_party/SPIRV-Tools/source/opt/const_folding_rules.cpp
@@ -21,6 +21,59 @@ namespace opt {
namespace {
constexpr uint32_t kExtractCompositeIdInIdx = 0;
+// Returns the value obtained by extracting the |number_of_bits| least
+// significant bits from |value|, and sign-extending it to 64-bits.
+uint64_t SignExtendValue(uint64_t value, uint32_t number_of_bits) {
+ if (number_of_bits == 64) return value;
+
+ uint64_t mask_for_sign_bit = 1ull << (number_of_bits - 1);
+ uint64_t mask_for_significant_bits = (mask_for_sign_bit << 1) - 1ull;
+ if (value & mask_for_sign_bit) {
+ // Set upper bits to 1
+ value |= ~mask_for_significant_bits;
+ } else {
+ // Clear the upper bits
+ value &= mask_for_significant_bits;
+ }
+ return value;
+}
+
+// Returns the value obtained by extracting the |number_of_bits| least
+// significant bits from |value|, and zero-extending it to 64-bits.
+uint64_t ZeroExtendValue(uint64_t value, uint32_t number_of_bits) {
+ if (number_of_bits == 64) return value;
+
+ uint64_t mask_for_first_bit_to_clear = 1ull << (number_of_bits);
+ uint64_t mask_for_bits_to_keep = mask_for_first_bit_to_clear - 1;
+ value &= mask_for_bits_to_keep;
+ return value;
+}
+
+// Returns a constant whose value is `value` and type is `type`. This constant
+// will be generated by `const_mgr`. The type must be a scalar integer type.
+const analysis::Constant* GenerateIntegerConstant(
+ const analysis::Integer* integer_type, uint64_t result,
+ analysis::ConstantManager* const_mgr) {
+ assert(integer_type != nullptr);
+
+ std::vector<uint32_t> words;
+ if (integer_type->width() == 64) {
+ // In the 64-bit case, two words are needed to represent the value.
+ words = {static_cast<uint32_t>(result),
+ static_cast<uint32_t>(result >> 32)};
+ } else {
+ // In all other cases, only a single word is needed.
+ assert(integer_type->width() <= 32);
+ if (integer_type->IsSigned()) {
+ result = SignExtendValue(result, integer_type->width());
+ } else {
+ result = ZeroExtendValue(result, integer_type->width());
+ }
+ words = {static_cast<uint32_t>(result)};
+ }
+ return const_mgr->GetConstant(integer_type, words);
+}
+
// Returns a constants with the value NaN of the given type. Only works for
// 32-bit and 64-bit float point types. Returns |nullptr| if an error occurs.
const analysis::Constant* GetNan(const analysis::Type* type,
@@ -88,6 +141,22 @@ const analysis::Constant* NegateFPConst(const analysis::Type* result_type,
return nullptr;
}
+// Returns a constants with the value |-val| of the given type.
+const analysis::Constant* NegateIntConst(const analysis::Type* result_type,
+ const analysis::Constant* val,
+ analysis::ConstantManager* const_mgr) {
+ const analysis::Integer* int_type = result_type->AsInteger();
+ assert(int_type != nullptr);
+
+ if (val->AsNullConstant()) {
+ return val;
+ }
+
+ uint64_t new_value = static_cast<uint64_t>(-val->GetSignExtendedValue());
+ return const_mgr->GetIntConst(new_value, int_type->width(),
+ int_type->IsSigned());
+}
+
// Folds an OpcompositeExtract where input is a composite constant.
ConstantFoldingRule FoldExtractWithConstants() {
return [](IRContext* context, Instruction* inst,
@@ -341,6 +410,69 @@ ConstantFoldingRule FoldVectorTimesScalar() {
};
}
+// Returns to the constant that results from tranposing |matrix|. The result
+// will have type |result_type|, and |matrix| must exist in |context|. The
+// result constant will also exist in |context|.
+const analysis::Constant* TransposeMatrix(const analysis::Constant* matrix,
+ analysis::Matrix* result_type,
+ IRContext* context) {
+ analysis::ConstantManager* const_mgr = context->get_constant_mgr();
+ if (matrix->AsNullConstant() != nullptr) {
+ return const_mgr->GetNullCompositeConstant(result_type);
+ }
+
+ const auto& columns = matrix->AsMatrixConstant()->GetComponents();
+ uint32_t number_of_rows = columns[0]->type()->AsVector()->element_count();
+
+ // Collect the ids of the elements in their new positions.
+ std::vector<std::vector<uint32_t>> result_elements(number_of_rows);
+ for (const analysis::Constant* column : columns) {
+ if (column->AsNullConstant()) {
+ column = const_mgr->GetNullCompositeConstant(column->type());
+ }
+ const auto& column_components = column->AsVectorConstant()->GetComponents();
+
+ for (uint32_t row = 0; row < number_of_rows; ++row) {
+ result_elements[row].push_back(
+ const_mgr->GetDefiningInstruction(column_components[row])
+ ->result_id());
+ }
+ }
+
+ // Create the constant for each row in the result, and collect the ids.
+ std::vector<uint32_t> result_columns(number_of_rows);
+ for (uint32_t col = 0; col < number_of_rows; ++col) {
+ auto* element = const_mgr->GetConstant(result_type->element_type(),
+ result_elements[col]);
+ result_columns[col] =
+ const_mgr->GetDefiningInstruction(element)->result_id();
+ }
+
+ // Create the matrix constant from the row ids, and return it.
+ return const_mgr->GetConstant(result_type, result_columns);
+}
+
+const analysis::Constant* FoldTranspose(
+ IRContext* context, Instruction* inst,
+ const std::vector<const analysis::Constant*>& constants) {
+ assert(inst->opcode() == spv::Op::OpTranspose);
+
+ analysis::TypeManager* type_mgr = context->get_type_mgr();
+ if (!inst->IsFloatingPointFoldingAllowed()) {
+ if (HasFloatingPoint(type_mgr->GetType(inst->type_id()))) {
+ return nullptr;
+ }
+ }
+
+ const analysis::Constant* matrix = constants[0];
+ if (matrix == nullptr) {
+ return nullptr;
+ }
+
+ auto* result_type = type_mgr->GetType(inst->type_id());
+ return TransposeMatrix(matrix, result_type->AsMatrix(), context);
+}
+
ConstantFoldingRule FoldVectorTimesMatrix() {
return [](IRContext* context, Instruction* inst,
const std::vector<const analysis::Constant*>& constants)
@@ -376,13 +508,7 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
assert(c1->type()->AsVector()->element_type() == element_type &&
c2->type()->AsMatrix()->element_type() == vector_type);
- // Get a float vector that is the result of vector-times-matrix.
- std::vector<const analysis::Constant*> c1_components =
- c1->GetVectorComponents(const_mgr);
- std::vector<const analysis::Constant*> c2_components =
- c2->AsMatrixConstant()->GetComponents();
uint32_t resultVectorSize = result_type->AsVector()->element_count();
-
std::vector<uint32_t> ids;
if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) {
@@ -395,6 +521,12 @@ ConstantFoldingRule FoldVectorTimesMatrix() {
return const_mgr->GetConstant(vector_type, ids);
}
+ // Get a float vector that is the result of vector-times-matrix.
+ std::vector<const analysis::Constant*> c1_components =
+ c1->GetVectorComponents(const_mgr);
+ std::vector<const analysis::Constant*> c2_components =
+ c2->AsMatrixConstant()->GetComponents();
+
if (float_type->width() == 32) {
for (uint32_t i = 0; i < resultVectorSize; ++i) {
float result_scalar = 0.0f;
@@ -472,13 +604,7 @@ ConstantFoldingRule FoldMatrixTimesVector() {
assert(c1->type()->AsMatrix()->element_type() == vector_type);
assert(c2->type()->AsVector()->element_type() == element_type);
- // Get a float vector that is the result of matrix-times-vector.
- std::vector<const analysis::Constant*> c1_components =
- c1->AsMatrixConstant()->GetComponents();
- std::vector<const analysis::Constant*> c2_components =
- c2->GetVectorComponents(const_mgr);
uint32_t resultVectorSize = result_type->AsVector()->element_count();
-
std::vector<uint32_t> ids;
if ((c1 && c1->IsZero()) || (c2 && c2->IsZero())) {
@@ -491,6 +617,12 @@ ConstantFoldingRule FoldMatrixTimesVector() {
return const_mgr->GetConstant(vector_type, ids);
}
+ // Get a float vector that is the result of matrix-times-vector.
+ std::vector<const analysis::Constant*> c1_components =
+ c1->AsMatrixConstant()->GetComponents();
+ std::vector<const analysis::Constant*> c2_components =
+ c2->GetVectorComponents(const_mgr);
+
if (float_type->width() == 32) {
for (uint32_t i = 0; i < resultVectorSize; ++i) {
float result_scalar = 0.0f;
@@ -587,13 +719,13 @@ using BinaryScalarFoldingRule = std::function<const analysis::Constant*(
const analysis::Type* result_type, const analysis::Constant* a,
const analysis::Constant* b, analysis::ConstantManager*)>;
-// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops
-// using |scalar_rule| and unary float point vectors ops by applying
+// Returns a |ConstantFoldingRule| that folds unary scalar ops
+// using |scalar_rule| and unary vectors ops by applying
// |scalar_rule| to the elements of the vector. The |ConstantFoldingRule|
// that is returned assumes that |constants| contains 1 entry. If they are
// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector|
// whose element type is |Float| or |Integer|.
-ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {
+ConstantFoldingRule FoldUnaryOp(UnaryScalarFoldingRule scalar_rule) {
return [scalar_rule](IRContext* context, Instruction* inst,
const std::vector<const analysis::Constant*>& constants)
-> const analysis::Constant* {
@@ -602,10 +734,6 @@ ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {
const analysis::Type* result_type = type_mgr->GetType(inst->type_id());
const analysis::Vector* vector_type = result_type->AsVector();
- if (!inst->IsFloatingPointFoldingAllowed()) {
- return nullptr;
- }
-
const analysis::Constant* arg =
(inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0];
@@ -640,6 +768,83 @@ ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {
};
}
+// Returns a |ConstantFoldingRule| that folds binary scalar ops
+// using |scalar_rule| and binary vectors ops by applying
+// |scalar_rule| to the elements of the vector. The folding rule assumes that op
+// has two inputs. For regular instruction, those are in operands 0 and 1. For
+// extended instruction, they are in operands 1 and 2. If an element in
+// |constants| is not nullprt, then the constant's type is |Float|, |Integer|,
+// or |Vector| whose element type is |Float| or |Integer|.
+ConstantFoldingRule FoldBinaryOp(BinaryScalarFoldingRule scalar_rule) {
+ return [scalar_rule](IRContext* context, Instruction* inst,
+ const std::vector<const analysis::Constant*>& constants)
+ -> const analysis::Constant* {
+ assert(constants.size() == inst->NumInOperands());
+ assert(constants.size() == (inst->opcode() == spv::Op::OpExtInst ? 3 : 2));
+ analysis::ConstantManager* const_mgr = context->get_constant_mgr();
+ analysis::TypeManager* type_mgr = context->get_type_mgr();
+ const analysis::Type* result_type = type_mgr->GetType(inst->type_id());
+ const analysis::Vector* vector_type = result_type->AsVector();
+
+ const analysis::Constant* arg1 =
+ (inst->opcode() == spv::Op::OpExtInst) ? constants[1] : constants[0];
+ const analysis::Constant* arg2 =
+ (inst->opcode() == spv::Op::OpExtInst) ? constants[2] : constants[1];
+
+ if (arg1 == nullptr || arg2 == nullptr) {
+ return nullptr;
+ }
+
+ if (vector_type == nullptr) {
+ return scalar_rule(result_type, arg1, arg2, const_mgr);
+ }
+
+ std::vector<const analysis::Constant*> a_components;
+ std::vector<const analysis::Constant*> b_components;
+ std::vector<const analysis::Constant*> results_components;
+
+ a_components = arg1->GetVectorComponents(const_mgr);
+ b_components = arg2->GetVectorComponents(const_mgr);
+ assert(a_components.size() == b_components.size());
+
+ // Fold each component of the vector.
+ for (uint32_t i = 0; i < a_components.size(); ++i) {
+ results_components.push_back(scalar_rule(vector_type->element_type(),
+ a_components[i], b_components[i],
+ const_mgr));
+ if (results_components[i] == nullptr) {
+ return nullptr;
+ }
+ }
+
+ // Build the constant object and return it.
+ std::vector<uint32_t> ids;
+ for (const analysis::Constant* member : results_components) {
+ ids.push_back(const_mgr->GetDefiningInstruction(member)->result_id());
+ }
+ return const_mgr->GetConstant(vector_type, ids);
+ };
+}
+
+// Returns a |ConstantFoldingRule| that folds unary floating point scalar ops
+// using |scalar_rule| and unary float point vectors ops by applying
+// |scalar_rule| to the elements of the vector. The |ConstantFoldingRule|
+// that is returned assumes that |constants| contains 1 entry. If they are
+// not |nullptr|, then their type is either |Float| or |Integer| or a |Vector|
+// whose element type is |Float| or |Integer|.
+ConstantFoldingRule FoldFPUnaryOp(UnaryScalarFoldingRule scalar_rule) {
+ auto folding_rule = FoldUnaryOp(scalar_rule);
+ return [folding_rule](IRContext* context, Instruction* inst,
+ const std::vector<const analysis::Constant*>& constants)
+ -> const analysis::Constant* {
+ if (!inst->IsFloatingPointFoldingAllowed()) {
+ return nullptr;
+ }
+
+ return folding_rule(context, inst, constants);
+ };
+}
+
// Returns the result of folding the constants in |constants| according the
// |scalar_rule|. If |result_type| is a vector, then |scalar_rule| is applied
// per component.
@@ -872,6 +1077,11 @@ const analysis::Constant* FoldScalarFPDivide(
return FoldFPScalarDivideByZero(result_type, numerator, const_mgr);
}
+ uint32_t width = denominator->type()->AsFloat()->width();
+ if (width != 32 && width != 64) {
+ return nullptr;
+ }
+
const analysis::FloatConstant* denominator_float =
denominator->AsFloatConstant();
if (denominator_float && denominator->GetValueAsDouble() == -0.0) {
@@ -1042,18 +1252,8 @@ ConstantFoldingRule FoldOpDotWithConstants() {
};
}
-// This function defines a |UnaryScalarFoldingRule| that subtracts the constant
-// from zero.
-UnaryScalarFoldingRule FoldFNegateOp() {
- return [](const analysis::Type* result_type, const analysis::Constant* a,
- analysis::ConstantManager* const_mgr) -> const analysis::Constant* {
- assert(result_type != nullptr && a != nullptr);
- assert(result_type == a->type());
- return NegateFPConst(result_type, a, const_mgr);
- };
-}
-
-ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(FoldFNegateOp()); }
+ConstantFoldingRule FoldFNegate() { return FoldFPUnaryOp(NegateFPConst); }
+ConstantFoldingRule FoldSNegate() { return FoldUnaryOp(NegateIntConst); }
ConstantFoldingRule FoldFClampFeedingCompare(spv::Op cmp_opcode) {
return [cmp_opcode](IRContext* context, Instruction* inst,
@@ -1497,6 +1697,74 @@ BinaryScalarFoldingRule FoldFTranscendentalBinary(double (*fp)(double,
return nullptr;
};
}
+
+enum Sign { Signed, Unsigned };
+
+// Returns a BinaryScalarFoldingRule that applies `op` to the scalars.
+// The `signedness` is used to determine if the operands should be interpreted
+// as signed or unsigned. If the operands are signed, the value will be sign
+// extended before the value is passed to `op`. Otherwise the values will be
+// zero extended.
+template <Sign signedness>
+BinaryScalarFoldingRule FoldBinaryIntegerOperation(uint64_t (*op)(uint64_t,
+ uint64_t)) {
+ return
+ [op](const analysis::Type* result_type, const analysis::Constant* a,
+ const analysis::Constant* b,
+ analysis::ConstantManager* const_mgr) -> const analysis::Constant* {
+ assert(result_type != nullptr && a != nullptr && b != nullptr);
+ const analysis::Integer* integer_type = result_type->AsInteger();
+ assert(integer_type != nullptr);
+ assert(a->type()->kind() == analysis::Type::kInteger);
+ assert(b->type()->kind() == analysis::Type::kInteger);
+ assert(integer_type->width() == a->type()->AsInteger()->width());
+ assert(integer_type->width() == b->type()->AsInteger()->width());
+
+ // In SPIR-V, all operations support unsigned types, but the way they
+ // are interpreted depends on the opcode. This is why we use the
+ // template argument to determine how to interpret the operands.
+ uint64_t ia = (signedness == Signed ? a->GetSignExtendedValue()
+ : a->GetZeroExtendedValue());
+ uint64_t ib = (signedness == Signed ? b->GetSignExtendedValue()
+ : b->GetZeroExtendedValue());
+ uint64_t result = op(ia, ib);
+
+ const analysis::Constant* result_constant =
+ GenerateIntegerConstant(integer_type, result, const_mgr);
+ return result_constant;
+ };
+}
+
+// A scalar folding rule that folds OpSConvert.
+const analysis::Constant* FoldScalarSConvert(
+ const analysis::Type* result_type, const analysis::Constant* a,
+ analysis::ConstantManager* const_mgr) {
+ assert(result_type != nullptr);
+ assert(a != nullptr);
+ assert(const_mgr != nullptr);
+ const analysis::Integer* integer_type = result_type->AsInteger();
+ assert(integer_type && "The result type of an SConvert");
+ int64_t value = a->GetSignExtendedValue();
+ return GenerateIntegerConstant(integer_type, value, const_mgr);
+}
+
+// A scalar folding rule that folds OpUConvert.
+const analysis::Constant* FoldScalarUConvert(
+ const analysis::Type* result_type, const analysis::Constant* a,
+ analysis::ConstantManager* const_mgr) {
+ assert(result_type != nullptr);
+ assert(a != nullptr);
+ assert(const_mgr != nullptr);
+ const analysis::Integer* integer_type = result_type->AsInteger();
+ assert(integer_type && "The result type of an UConvert");
+ uint64_t value = a->GetZeroExtendedValue();
+
+ // If the operand was an unsigned value with less than 32-bit, it would have
+ // been sign extended earlier, and we need to clear those bits.
+ auto* operand_type = a->type()->AsInteger();
+ value = ZeroExtendValue(value, operand_type->width());
+ return GenerateIntegerConstant(integer_type, value, const_mgr);
+}
} // namespace
void ConstantFoldingRules::AddFoldingRules() {
@@ -1514,6 +1782,8 @@ void ConstantFoldingRules::AddFoldingRules() {
rules_[spv::Op::OpConvertFToU].push_back(FoldFToI());
rules_[spv::Op::OpConvertSToF].push_back(FoldIToF());
rules_[spv::Op::OpConvertUToF].push_back(FoldIToF());
+ rules_[spv::Op::OpSConvert].push_back(FoldUnaryOp(FoldScalarSConvert));
+ rules_[spv::Op::OpUConvert].push_back(FoldUnaryOp(FoldScalarUConvert));
rules_[spv::Op::OpDot].push_back(FoldOpDotWithConstants());
rules_[spv::Op::OpFAdd].push_back(FoldFAdd());
@@ -1566,10 +1836,52 @@ void ConstantFoldingRules::AddFoldingRules() {
rules_[spv::Op::OpVectorTimesScalar].push_back(FoldVectorTimesScalar());
rules_[spv::Op::OpVectorTimesMatrix].push_back(FoldVectorTimesMatrix());
rules_[spv::Op::OpMatrixTimesVector].push_back(FoldMatrixTimesVector());
+ rules_[spv::Op::OpTranspose].push_back(FoldTranspose);
rules_[spv::Op::OpFNegate].push_back(FoldFNegate());
+ rules_[spv::Op::OpSNegate].push_back(FoldSNegate());
rules_[spv::Op::OpQuantizeToF16].push_back(FoldQuantizeToF16());
+ rules_[spv::Op::OpIAdd].push_back(
+ FoldBinaryOp(FoldBinaryIntegerOperation<Unsigned>(
+ [](uint64_t a, uint64_t b) { return a + b; })));
+ rules_[spv::Op::OpISub].push_back(
+ FoldBinaryOp(FoldBinaryIntegerOperation<Unsigned>(
+ [](uint64_t a, uint64_t b) { return a - b; })));
+ rules_[spv::Op::OpIMul].push_back(
+ FoldBinaryOp(FoldBinaryIntegerOperation<Unsigned>(
+ [](uint64_t a, uint64_t b) { return a * b; })));
+ rules_[spv::Op::OpUDiv].push_back(
+ FoldBinaryOp(FoldBinaryIntegerOperation<Unsigned>(
+ [](uint64_t a, uint64_t b) { return (b != 0 ? a / b : 0); })));
+ rules_[spv::Op::OpSDiv].push_back(FoldBinaryOp(
+ FoldBinaryIntegerOperation<Signed>([](uint64_t a, uint64_t b) {
+ return (b != 0 ? static_cast<uint64_t>(static_cast<int64_t>(a) /
+ static_cast<int64_t>(b))
+ : 0);
+ })));
+ rules_[spv::Op::OpUMod].push_back(
+ FoldBinaryOp(FoldBinaryIntegerOperation<Unsigned>(
+ [](uint64_t a, uint64_t b) { return (b != 0 ? a % b : 0); })));
+
+ rules_[spv::Op::OpSRem].push_back(FoldBinaryOp(
+ FoldBinaryIntegerOperation<Signed>([](uint64_t a, uint64_t b) {
+ return (b != 0 ? static_cast<uint64_t>(static_cast<int64_t>(a) %
+ static_cast<int64_t>(b))
+ : 0);
+ })));
+
+ rules_[spv::Op::OpSMod].push_back(FoldBinaryOp(
+ FoldBinaryIntegerOperation<Signed>([](uint64_t a, uint64_t b) {
+ if (b == 0) return static_cast<uint64_t>(0ull);
+
+ int64_t signed_a = static_cast<int64_t>(a);
+ int64_t signed_b = static_cast<int64_t>(b);
+ int64_t result = signed_a % signed_b;
+ if ((signed_b < 0) != (result < 0)) result += signed_b;
+ return static_cast<uint64_t>(result);
+ })));
+
// Add rules for GLSLstd450
FeatureManager* feature_manager = context_->get_feature_mgr();
uint32_t ext_inst_glslstd450_id =
diff --git a/third_party/SPIRV-Tools/source/opt/constants.cpp b/third_party/SPIRV-Tools/source/opt/constants.cpp
index 9b4c89a65..6eebbb572 100644
--- a/third_party/SPIRV-Tools/source/opt/constants.cpp
+++ b/third_party/SPIRV-Tools/source/opt/constants.cpp
@@ -435,6 +435,8 @@ const Constant* ConstantManager::GetNumericVectorConstantWithWords(
words_per_element = float_type->width() / 32;
else if (const auto* int_type = element_type->AsInteger())
words_per_element = int_type->width() / 32;
+ else if (element_type->AsBool() != nullptr)
+ words_per_element = 1;
if (words_per_element != 1 && words_per_element != 2) return nullptr;
@@ -487,6 +489,31 @@ uint32_t ConstantManager::GetSIntConstId(int32_t val) {
return GetDefiningInstruction(c)->result_id();
}
+const Constant* ConstantManager::GetIntConst(uint64_t val, int32_t bitWidth,
+ bool isSigned) {
+ Type* int_type = context()->get_type_mgr()->GetIntType(bitWidth, isSigned);
+
+ if (isSigned) {
+ // Sign extend the value.
+ int32_t num_of_bit_to_ignore = 64 - bitWidth;
+ val = static_cast<int64_t>(val << num_of_bit_to_ignore) >>
+ num_of_bit_to_ignore;
+ } else if (bitWidth < 64) {
+ // Clear the upper bit that are not used.
+ uint64_t mask = ((1ull << bitWidth) - 1);
+ val &= mask;
+ }
+
+ if (bitWidth <= 32) {
+ return GetConstant(int_type, {static_cast<uint32_t>(val)});
+ }
+
+ // If the value is more than 32-bit, we need to split the operands into two
+ // 32-bit integers.
+ return GetConstant(
+ int_type, {static_cast<uint32_t>(val), static_cast<uint32_t>(val >> 32)});
+}
+
uint32_t ConstantManager::GetUIntConstId(uint32_t val) {
Type* uint_type = context()->get_type_mgr()->GetUIntType();
const Constant* c = GetConstant(uint_type, {val});
diff --git a/third_party/SPIRV-Tools/source/opt/constants.h b/third_party/SPIRV-Tools/source/opt/constants.h
index 410304eae..ae8dc6259 100644
--- a/third_party/SPIRV-Tools/source/opt/constants.h
+++ b/third_party/SPIRV-Tools/source/opt/constants.h
@@ -659,6 +659,12 @@ class ConstantManager {
// Returns the id of a 32-bit signed integer constant with value |val|.
uint32_t GetSIntConstId(int32_t val);
+ // Returns an integer constant with `bitWidth` and value |val|. If `isSigned`
+ // is true, the constant will be a signed integer. Otherwise it will be
+ // unsigned. Only the `bitWidth` lower order bits of |val| will be used. The
+ // rest will be ignored.
+ const Constant* GetIntConst(uint64_t val, int32_t bitWidth, bool isSigned);
+
// Returns the id of a 32-bit unsigned integer constant with value |val|.
uint32_t GetUIntConstId(uint32_t val);
diff --git a/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.cpp b/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.cpp
index 2c4a631e1..e243bedf0 100644
--- a/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.cpp
@@ -63,6 +63,10 @@ bool ConvertToHalfPass::IsRelaxed(uint32_t id) {
void ConvertToHalfPass::AddRelaxed(uint32_t id) { relaxed_ids_set_.insert(id); }
+bool ConvertToHalfPass::CanRelaxOpOperands(Instruction* inst) {
+ return image_ops_.count(inst->opcode()) == 0;
+}
+
analysis::Type* ConvertToHalfPass::FloatScalarType(uint32_t width) {
analysis::Float float_ty(width);
return context()->get_type_mgr()->GetRegisteredType(&float_ty);
@@ -167,6 +171,19 @@ bool ConvertToHalfPass::RemoveRelaxedDecoration(uint32_t id) {
bool ConvertToHalfPass::GenHalfArith(Instruction* inst) {
bool modified = false;
+ // If this is a OpCompositeExtract instruction and has a struct operand, we
+ // should not relax this instruction. Doing so could cause a mismatch between
+ // the result type and the struct member type.
+ bool hasStructOperand = false;
+ if (inst->opcode() == spv::Op::OpCompositeExtract) {
+ inst->ForEachInId([&hasStructOperand, this](uint32_t* idp) {
+ Instruction* op_inst = get_def_use_mgr()->GetDef(*idp);
+ if (IsStruct(op_inst)) hasStructOperand = true;
+ });
+ if (hasStructOperand) {
+ return false;
+ }
+ }
// Convert all float32 based operands to float16 equivalent and change
// instruction type to float16 equivalent.
inst->ForEachInId([&inst, &modified, this](uint32_t* idp) {
@@ -299,12 +316,19 @@ bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) {
if (closure_ops_.count(inst->opcode()) == 0) return false;
// Can relax if all float operands are relaxed
bool relax = true;
- inst->ForEachInId([&relax, this](uint32_t* idp) {
+ bool hasStructOperand = false;
+ inst->ForEachInId([&relax, &hasStructOperand, this](uint32_t* idp) {
Instruction* op_inst = get_def_use_mgr()->GetDef(*idp);
- if (IsStruct(op_inst)) relax = false;
+ if (IsStruct(op_inst)) hasStructOperand = true;
if (!IsFloat(op_inst, 32)) return;
if (!IsRelaxed(*idp)) relax = false;
});
+ // If the instruction has a struct operand, we should not relax it, even if
+ // all its uses are relaxed. Doing so could cause a mismatch between the
+ // result type and the struct member type.
+ if (hasStructOperand) {
+ return false;
+ }
if (relax) {
AddRelaxed(inst->result_id());
return true;
@@ -313,7 +337,8 @@ bool ConvertToHalfPass::CloseRelaxInst(Instruction* inst) {
relax = true;
get_def_use_mgr()->ForEachUser(inst, [&relax, this](Instruction* uinst) {
if (uinst->result_id() == 0 || !IsFloat(uinst, 32) ||
- (!IsDecoratedRelaxed(uinst) && !IsRelaxed(uinst->result_id()))) {
+ (!IsDecoratedRelaxed(uinst) && !IsRelaxed(uinst->result_id())) ||
+ !CanRelaxOpOperands(uinst)) {
relax = false;
return;
}
diff --git a/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.h b/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.h
index 24a478ffc..8e10c4fb9 100644
--- a/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/convert_to_half_pass.h
@@ -56,6 +56,9 @@ class ConvertToHalfPass : public Pass {
// Add |id| to the relaxed id set
void AddRelaxed(uint32_t id);
+ // Return true if the instruction's operands can be relaxed
+ bool CanRelaxOpOperands(Instruction* inst);
+
// Return type id for float with |width|
analysis::Type* FloatScalarType(uint32_t width);
@@ -133,13 +136,13 @@ class ConvertToHalfPass : public Pass {
// Set of 450 extension operations to be processed
std::unordered_set<uint32_t> target_ops_450_;
- // Set of sample operations
+ // Set of all sample operations, including dref and non-dref operations
std::unordered_set<spv::Op, hasher> image_ops_;
- // Set of dref sample operations
+ // Set of only dref sample operations
std::unordered_set<spv::Op, hasher> dref_image_ops_;
- // Set of dref sample operations
+ // Set of operations that can be marked as relaxed
std::unordered_set<spv::Op, hasher> closure_ops_;
// Set of ids of all relaxed instructions
diff --git a/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.cpp b/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.cpp
index 66a268fba..c2bea8ad0 100644
--- a/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.cpp
+++ b/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.cpp
@@ -35,6 +35,32 @@ bool IsDebugDeclareOrValue(Instruction* di) {
dbg_opcode == CommonDebugInfoDebugValue;
}
+// Returns the number of members in |type|. If |type| is not a composite type
+// or the number of components is not known at compile time, the return value
+// will be 0.
+uint32_t GetNumberOfMembers(const analysis::Type* type, IRContext* context) {
+ if (const analysis::Struct* struct_type = type->AsStruct()) {
+ return static_cast<uint32_t>(struct_type->element_types().size());
+ } else if (const analysis::Array* array_type = type->AsArray()) {
+ const analysis::Constant* length_const =
+ context->get_constant_mgr()->FindDeclaredConstant(
+ array_type->LengthId());
+
+ if (length_const == nullptr) {
+ // This can happen if the length is an OpSpecConstant.
+ return 0;
+ }
+ assert(length_const->type()->AsInteger());
+ return length_const->GetU32();
+ } else if (const analysis::Vector* vector_type = type->AsVector()) {
+ return vector_type->element_count();
+ } else if (const analysis::Matrix* matrix_type = type->AsMatrix()) {
+ return matrix_type->element_count();
+ } else {
+ return 0;
+ }
+}
+
} // namespace
Pass::Status CopyPropagateArrays::Process() {
@@ -357,22 +383,9 @@ CopyPropagateArrays::BuildMemoryObjectFromInsert(Instruction* insert_inst) {
analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
analysis::TypeManager* type_mgr = context()->get_type_mgr();
- analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
const analysis::Type* result_type = type_mgr->GetType(insert_inst->type_id());
- uint32_t number_of_elements = 0;
- if (const analysis::Struct* struct_type = result_type->AsStruct()) {
- number_of_elements =
- static_cast<uint32_t>(struct_type->element_types().size());
- } else if (const analysis::Array* array_type = result_type->AsArray()) {
- const analysis::Constant* length_const =
- const_mgr->FindDeclaredConstant(array_type->LengthId());
- number_of_elements = length_const->GetU32();
- } else if (const analysis::Vector* vector_type = result_type->AsVector()) {
- number_of_elements = vector_type->element_count();
- } else if (const analysis::Matrix* matrix_type = result_type->AsMatrix()) {
- number_of_elements = matrix_type->element_count();
- }
+ uint32_t number_of_elements = GetNumberOfMembers(result_type, context());
if (number_of_elements == 0) {
return nullptr;
@@ -800,23 +813,8 @@ uint32_t CopyPropagateArrays::MemoryObject::GetNumberOfMembers() {
std::vector<uint32_t> access_indices = GetAccessIds();
type = type_mgr->GetMemberType(type, access_indices);
- if (const analysis::Struct* struct_type = type->AsStruct()) {
- return static_cast<uint32_t>(struct_type->element_types().size());
- } else if (const analysis::Array* array_type = type->AsArray()) {
- const analysis::Constant* length_const =
- context->get_constant_mgr()->FindDeclaredConstant(
- array_type->LengthId());
- assert(length_const->type()->AsInteger());
- return length_const->GetU32();
- } else if (const analysis::Vector* vector_type = type->AsVector()) {
- return vector_type->element_count();
- } else if (const analysis::Matrix* matrix_type = type->AsMatrix()) {
- return matrix_type->element_count();
- } else {
- return 0;
- }
+ return opt::GetNumberOfMembers(type, context);
}
-
template <class iterator>
CopyPropagateArrays::MemoryObject::MemoryObject(Instruction* var_inst,
iterator begin, iterator end)
diff --git a/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.h b/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.h
index 7486f8086..c6ca7d251 100644
--- a/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.h
+++ b/third_party/SPIRV-Tools/source/opt/copy_prop_arrays.h
@@ -101,7 +101,8 @@ class CopyPropagateArrays : public MemPass {
bool IsMember() const { return !access_chain_.empty(); }
// Returns the number of members in the object represented by |this|. If
- // |this| does not represent a composite type, the return value will be 0.
+ // |this| does not represent a composite type or the number of components is
+ // not known at compile time, the return value will be 0.
uint32_t GetNumberOfMembers();
// Returns the owning variable that the memory object is contained in.
@@ -207,7 +208,7 @@ class CopyPropagateArrays : public MemPass {
// Returns the memory object that at some point was equivalent to the result
// of |insert_inst|. If a memory object cannot be identified, the return
- // value is |nullptr\. The opcode of |insert_inst| must be
+ // value is |nullptr|. The opcode of |insert_inst| must be
// |OpCompositeInsert|. This function looks for a series of
// |OpCompositeInsert| instructions that insert the elements one at a time in
// order from beginning to end.
diff --git a/third_party/SPIRV-Tools/source/opt/dead_insert_elim_pass.cpp b/third_party/SPIRV-Tools/source/opt/dead_insert_elim_pass.cpp
index a48690374..f985e4c26 100644
--- a/third_party/SPIRV-Tools/source/opt/dead_insert_elim_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/dead_insert_elim_pass.cpp
@@ -213,7 +213,8 @@ bool DeadInsertElimPass::EliminateDeadInsertsOnePass(Function* func) {
} break;
default: {
// Mark inserts in chain for all components
- MarkInsertChain(&*ii, nullptr, 0, nullptr);
+ std::unordered_set<uint32_t> visited_phis;
+ MarkInsertChain(&*ii, nullptr, 0, &visited_phis);
} break;
}
});
diff --git a/third_party/SPIRV-Tools/source/opt/decoration_manager.cpp b/third_party/SPIRV-Tools/source/opt/decoration_manager.cpp
index 1393d480e..3e95dbc35 100644
--- a/third_party/SPIRV-Tools/source/opt/decoration_manager.cpp
+++ b/third_party/SPIRV-Tools/source/opt/decoration_manager.cpp
@@ -461,7 +461,7 @@ std::vector<T> DecorationManager::InternalGetDecorationsFor(
bool DecorationManager::WhileEachDecoration(
uint32_t id, uint32_t decoration,
- std::function<bool(const Instruction&)> f) {
+ std::function<bool(const Instruction&)> f) const {
for (const Instruction* inst : GetDecorationsFor(id, true)) {
switch (inst->opcode()) {
case spv::Op::OpMemberDecorate:
@@ -485,14 +485,19 @@ bool DecorationManager::WhileEachDecoration(
void DecorationManager::ForEachDecoration(
uint32_t id, uint32_t decoration,
- std::function<void(const Instruction&)> f) {
+ std::function<void(const Instruction&)> f) const {
WhileEachDecoration(id, decoration, [&f](const Instruction& inst) {
f(inst);
return true;
});
}
-bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) {
+bool DecorationManager::HasDecoration(uint32_t id,
+ spv::Decoration decoration) const {
+ return HasDecoration(id, static_cast<uint32_t>(decoration));
+}
+
+bool DecorationManager::HasDecoration(uint32_t id, uint32_t decoration) const {
bool has_decoration = false;
ForEachDecoration(id, decoration, [&has_decoration](const Instruction&) {
has_decoration = true;
diff --git a/third_party/SPIRV-Tools/source/opt/decoration_manager.h b/third_party/SPIRV-Tools/source/opt/decoration_manager.h
index 1a0d1b183..2be016a71 100644
--- a/third_party/SPIRV-Tools/source/opt/decoration_manager.h
+++ b/third_party/SPIRV-Tools/source/opt/decoration_manager.h
@@ -92,20 +92,21 @@ class DecorationManager {
// Returns whether a decoration instruction for |id| with decoration
// |decoration| exists or not.
- bool HasDecoration(uint32_t id, uint32_t decoration);
+ bool HasDecoration(uint32_t id, uint32_t decoration) const;
+ bool HasDecoration(uint32_t id, spv::Decoration decoration) const;
// |f| is run on each decoration instruction for |id| with decoration
// |decoration|. Processed are all decorations which target |id| either
// directly or indirectly by Decoration Groups.
void ForEachDecoration(uint32_t id, uint32_t decoration,
- std::function<void(const Instruction&)> f);
+ std::function<void(const Instruction&)> f) const;
// |f| is run on each decoration instruction for |id| with decoration
// |decoration|. Processes all decoration which target |id| either directly or
// indirectly through decoration groups. If |f| returns false, iteration is
// terminated and this function returns false.
bool WhileEachDecoration(uint32_t id, uint32_t decoration,
- std::function<bool(const Instruction&)> f);
+ std::function<bool(const Instruction&)> f) const;
// |f| is run on each decoration instruction for |id| with decoration
// |decoration|. Processes all decoration which target |id| either directly or
@@ -141,7 +142,7 @@ class DecorationManager {
uint32_t decoration_value);
// Add |decoration, decoration_value| of |inst_id, member| to module.
- void AddMemberDecoration(uint32_t member, uint32_t inst_id,
+ void AddMemberDecoration(uint32_t inst_id, uint32_t member,
uint32_t decoration, uint32_t decoration_value);
friend bool operator==(const DecorationManager&, const DecorationManager&);
diff --git a/third_party/SPIRV-Tools/source/opt/def_use_manager.h b/third_party/SPIRV-Tools/source/opt/def_use_manager.h
index a8dbbc60b..13cf9bd3e 100644
--- a/third_party/SPIRV-Tools/source/opt/def_use_manager.h
+++ b/third_party/SPIRV-Tools/source/opt/def_use_manager.h
@@ -27,28 +27,6 @@ namespace spvtools {
namespace opt {
namespace analysis {
-// Class for representing a use of id. Note that:
-// * Result type id is a use.
-// * Ids referenced in OpSectionMerge & OpLoopMerge are considered as use.
-// * Ids referenced in OpPhi's in operands are considered as use.
-struct Use {
- Instruction* inst; // Instruction using the id.
- uint32_t operand_index; // logical operand index of the id use. This can be
- // the index of result type id.
-};
-
-inline bool operator==(const Use& lhs, const Use& rhs) {
- return lhs.inst == rhs.inst && lhs.operand_index == rhs.operand_index;
-}
-
-inline bool operator!=(const Use& lhs, const Use& rhs) { return !(lhs == rhs); }
-
-inline bool operator<(const Use& lhs, const Use& rhs) {
- if (lhs.inst < rhs.inst) return true;
- if (lhs.inst > rhs.inst) return false;
- return lhs.operand_index < rhs.operand_index;
-}
-
// Definition should never be null. User can be null, however, such an entry
// should be used only for searching (e.g. all users of a particular definition)
// and never stored in a container.
diff --git a/third_party/SPIRV-Tools/source/opt/desc_sroa.cpp b/third_party/SPIRV-Tools/source/opt/desc_sroa.cpp
index 8da0c864f..2c0f4829f 100644
--- a/third_party/SPIRV-Tools/source/opt/desc_sroa.cpp
+++ b/third_party/SPIRV-Tools/source/opt/desc_sroa.cpp
@@ -54,9 +54,10 @@ Pass::Status DescriptorScalarReplacement::Process() {
bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) {
std::vector<Instruction*> access_chain_work_list;
std::vector<Instruction*> load_work_list;
+ std::vector<Instruction*> entry_point_work_list;
bool failed = !get_def_use_mgr()->WhileEachUser(
- var->result_id(),
- [this, &access_chain_work_list, &load_work_list](Instruction* use) {
+ var->result_id(), [this, &access_chain_work_list, &load_work_list,
+ &entry_point_work_list](Instruction* use) {
if (use->opcode() == spv::Op::OpName) {
return true;
}
@@ -73,6 +74,9 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) {
case spv::Op::OpLoad:
load_work_list.push_back(use);
return true;
+ case spv::Op::OpEntryPoint:
+ entry_point_work_list.push_back(use);
+ return true;
default:
context()->EmitErrorMessage(
"Variable cannot be replaced: invalid instruction", use);
@@ -95,6 +99,11 @@ bool DescriptorScalarReplacement::ReplaceCandidate(Instruction* var) {
return false;
}
}
+ for (Instruction* use : entry_point_work_list) {
+ if (!ReplaceEntryPoint(var, use)) {
+ return false;
+ }
+ }
return true;
}
@@ -147,6 +156,42 @@ bool DescriptorScalarReplacement::ReplaceAccessChain(Instruction* var,
return true;
}
+bool DescriptorScalarReplacement::ReplaceEntryPoint(Instruction* var,
+ Instruction* use) {
+ // Build a new |OperandList| for |use| that removes |var| and adds its
+ // replacement variables.
+ Instruction::OperandList new_operands;
+
+ // Copy all operands except |var|.
+ bool found = false;
+ for (uint32_t idx = 0; idx < use->NumOperands(); idx++) {
+ Operand& op = use->GetOperand(idx);
+ if (op.type == SPV_OPERAND_TYPE_ID && op.words[0] == var->result_id()) {
+ found = true;
+ } else {
+ new_operands.emplace_back(op);
+ }
+ }
+
+ if (!found) {
+ context()->EmitErrorMessage(
+ "Variable cannot be replaced: invalid instruction", use);
+ return false;
+ }
+
+ // Add all new replacement variables.
+ uint32_t num_replacement_vars =
+ descsroautil::GetNumberOfElementsForArrayOrStruct(context(), var);
+ for (uint32_t i = 0; i < num_replacement_vars; i++) {
+ new_operands.push_back(
+ {SPV_OPERAND_TYPE_ID, {GetReplacementVariable(var, i)}});
+ }
+
+ use->ReplaceOperands(new_operands);
+ context()->UpdateDefUse(use);
+ return true;
+}
+
uint32_t DescriptorScalarReplacement::GetReplacementVariable(Instruction* var,
uint32_t idx) {
auto replacement_vars = replacement_variables_.find(var);
diff --git a/third_party/SPIRV-Tools/source/opt/desc_sroa.h b/third_party/SPIRV-Tools/source/opt/desc_sroa.h
index 6a24fd871..901be3e98 100644
--- a/third_party/SPIRV-Tools/source/opt/desc_sroa.h
+++ b/third_party/SPIRV-Tools/source/opt/desc_sroa.h
@@ -64,6 +64,11 @@ class DescriptorScalarReplacement : public Pass {
// otherwise.
bool ReplaceLoadedValue(Instruction* var, Instruction* value);
+ // Replaces the given composite variable |var| in the OpEntryPoint with the
+ // new replacement variables, one for each element of the array |var|. Returns
+ // |true| if successful, and |false| otherwise.
+ bool ReplaceEntryPoint(Instruction* var, Instruction* use);
+
// Replaces the given OpCompositeExtract |extract| and all of its references
// with an OpLoad of a replacement variable. |var| is the variable with
// composite type whose value is being used by |extract|. Assumes that
diff --git a/third_party/SPIRV-Tools/source/opt/feature_manager.cpp b/third_party/SPIRV-Tools/source/opt/feature_manager.cpp
index 07e053b8e..51883706a 100644
--- a/third_party/SPIRV-Tools/source/opt/feature_manager.cpp
+++ b/third_party/SPIRV-Tools/source/opt/feature_manager.cpp
@@ -40,31 +40,33 @@ void FeatureManager::AddExtension(Instruction* ext) {
const std::string name = ext->GetInOperand(0u).AsString();
Extension extension;
if (GetExtensionFromString(name.c_str(), &extension)) {
- extensions_.Add(extension);
+ extensions_.insert(extension);
}
}
void FeatureManager::RemoveExtension(Extension ext) {
- if (!extensions_.Contains(ext)) return;
- extensions_.Remove(ext);
+ if (!extensions_.contains(ext)) return;
+ extensions_.erase(ext);
}
void FeatureManager::AddCapability(spv::Capability cap) {
- if (capabilities_.Contains(cap)) return;
+ if (capabilities_.contains(cap)) return;
- capabilities_.Add(cap);
+ capabilities_.insert(cap);
spv_operand_desc desc = {};
if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
uint32_t(cap), &desc)) {
- CapabilitySet(desc->numCapabilities, desc->capabilities)
- .ForEach([this](spv::Capability c) { AddCapability(c); });
+ for (auto capability :
+ CapabilitySet(desc->numCapabilities, desc->capabilities)) {
+ AddCapability(capability);
+ }
}
}
void FeatureManager::RemoveCapability(spv::Capability cap) {
- if (!capabilities_.Contains(cap)) return;
- capabilities_.Remove(cap);
+ if (!capabilities_.contains(cap)) return;
+ capabilities_.erase(cap);
}
void FeatureManager::AddCapabilities(Module* module) {
diff --git a/third_party/SPIRV-Tools/source/opt/feature_manager.h b/third_party/SPIRV-Tools/source/opt/feature_manager.h
index b96988de4..d150a2fa2 100644
--- a/third_party/SPIRV-Tools/source/opt/feature_manager.h
+++ b/third_party/SPIRV-Tools/source/opt/feature_manager.h
@@ -25,27 +25,19 @@ namespace opt {
// Tracks features enabled by a module. The IRContext has a FeatureManager.
class FeatureManager {
public:
- explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {}
-
// Returns true if |ext| is an enabled extension in the module.
- bool HasExtension(Extension ext) const { return extensions_.Contains(ext); }
-
- // Removes the given |extension| from the current FeatureManager.
- void RemoveExtension(Extension extension);
+ bool HasExtension(Extension ext) const { return extensions_.contains(ext); }
// Returns true if |cap| is an enabled capability in the module.
bool HasCapability(spv::Capability cap) const {
- return capabilities_.Contains(cap);
+ return capabilities_.contains(cap);
}
- // Removes the given |capability| from the current FeatureManager.
- void RemoveCapability(spv::Capability capability);
-
- // Analyzes |module| and records enabled extensions and capabilities.
- void Analyze(Module* module);
+ // Returns the capabilities the module declares.
+ inline const CapabilitySet& GetCapabilities() const { return capabilities_; }
- CapabilitySet* GetCapabilities() { return &capabilities_; }
- const CapabilitySet* GetCapabilities() const { return &capabilities_; }
+ // Returns the extensions the module imports.
+ inline const ExtensionSet& GetExtensions() const { return extensions_; }
uint32_t GetExtInstImportId_GLSLstd450() const {
return extinst_importid_GLSLstd450_;
@@ -64,23 +56,34 @@ class FeatureManager {
return !(a == b);
}
- // Adds the given |capability| and all implied capabilities into the current
- // FeatureManager.
- void AddCapability(spv::Capability capability);
+ private:
+ explicit FeatureManager(const AssemblyGrammar& grammar) : grammar_(grammar) {}
+
+ // Analyzes |module| and records enabled extensions and capabilities.
+ void Analyze(Module* module);
// Add the extension |ext| to the feature manager.
void AddExtension(Instruction* ext);
- // Analyzes |module| and records imported external instruction sets.
- void AddExtInstImportIds(Module* module);
-
- private:
// Analyzes |module| and records enabled extensions.
void AddExtensions(Module* module);
+ // Removes the given |extension| from the current FeatureManager.
+ void RemoveExtension(Extension extension);
+
+ // Adds the given |capability| and all implied capabilities into the current
+ // FeatureManager.
+ void AddCapability(spv::Capability capability);
+
// Analyzes |module| and records enabled capabilities.
void AddCapabilities(Module* module);
+ // Removes the given |capability| from the current FeatureManager.
+ void RemoveCapability(spv::Capability capability);
+
+ // Analyzes |module| and records imported external instruction sets.
+ void AddExtInstImportIds(Module* module);
+
// Auxiliary object for querying SPIR-V grammar facts.
const AssemblyGrammar& grammar_;
@@ -100,6 +103,8 @@ class FeatureManager {
// Common NonSemanticShader100DebugInfo external instruction import ids,
// cached for performance.
uint32_t extinst_importid_Shader100DebugInfo_ = 0;
+
+ friend class IRContext;
};
} // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/fix_storage_class.cpp b/third_party/SPIRV-Tools/source/opt/fix_storage_class.cpp
index 5597e825b..564cd1b8a 100644
--- a/third_party/SPIRV-Tools/source/opt/fix_storage_class.cpp
+++ b/third_party/SPIRV-Tools/source/opt/fix_storage_class.cpp
@@ -318,7 +318,13 @@ uint32_t FixStorageClass::WalkAccessChainType(Instruction* inst, uint32_t id) {
const analysis::Constant* index_const =
context()->get_constant_mgr()->FindDeclaredConstant(
inst->GetSingleWordInOperand(i));
- uint32_t index = index_const->GetU32();
+ // It is highly unlikely that any type would have more fields than could
+ // be indexed by a 32-bit integer, and GetSingleWordInOperand only takes
+ // a 32-bit value, so we would not be able to handle it anyway. But the
+ // specification does allow any scalar integer type, treated as signed,
+ // so we simply downcast the index to 32-bits.
+ uint32_t index =
+ static_cast<uint32_t>(index_const->GetSignExtendedValue());
id = type_inst->GetSingleWordInOperand(index);
break;
}
diff --git a/third_party/SPIRV-Tools/source/opt/fold.cpp b/third_party/SPIRV-Tools/source/opt/fold.cpp
index 453756f8c..942da6835 100644
--- a/third_party/SPIRV-Tools/source/opt/fold.cpp
+++ b/third_party/SPIRV-Tools/source/opt/fold.cpp
@@ -70,58 +70,6 @@ uint32_t InstructionFolder::UnaryOperate(spv::Op opcode,
uint32_t InstructionFolder::BinaryOperate(spv::Op opcode, uint32_t a,
uint32_t b) const {
switch (opcode) {
- // Arthimetics
- case spv::Op::OpIAdd:
- return a + b;
- case spv::Op::OpISub:
- return a - b;
- case spv::Op::OpIMul:
- return a * b;
- case spv::Op::OpUDiv:
- if (b != 0) {
- return a / b;
- } else {
- // Dividing by 0 is undefined, so we will just pick 0.
- return 0;
- }
- case spv::Op::OpSDiv:
- if (b != 0u) {
- return (static_cast<int32_t>(a)) / (static_cast<int32_t>(b));
- } else {
- // Dividing by 0 is undefined, so we will just pick 0.
- return 0;
- }
- case spv::Op::OpSRem: {
- // The sign of non-zero result comes from the first operand: a. This is
- // guaranteed by C++11 rules for integer division operator. The division
- // result is rounded toward zero, so the result of '%' has the sign of
- // the first operand.
- if (b != 0u) {
- return static_cast<int32_t>(a) % static_cast<int32_t>(b);
- } else {
- // Remainder when dividing with 0 is undefined, so we will just pick 0.
- return 0;
- }
- }
- case spv::Op::OpSMod: {
- // The sign of non-zero result comes from the second operand: b
- if (b != 0u) {
- int32_t rem = BinaryOperate(spv::Op::OpSRem, a, b);
- int32_t b_prim = static_cast<int32_t>(b);
- return (rem + b_prim) % b_prim;
- } else {
- // Mod with 0 is undefined, so we will just pick 0.
- return 0;
- }
- }
- case spv::Op::OpUMod:
- if (b != 0u) {
- return (a % b);
- } else {
- // Mod with 0 is undefined, so we will just pick 0.
- return 0;
- }
-
// Shifting
case spv::Op::OpShiftRightLogical:
if (b >= 32) {
@@ -627,7 +575,8 @@ Instruction* InstructionFolder::FoldInstructionToConstant(
Instruction* inst, std::function<uint32_t(uint32_t)> id_map) const {
analysis::ConstantManager* const_mgr = context_->get_constant_mgr();
- if (!inst->IsFoldableByFoldScalar() && !HasConstFoldingRule(inst)) {
+ if (!inst->IsFoldableByFoldScalar() && !inst->IsFoldableByFoldVector() &&
+ !GetConstantFoldingRules().HasFoldingRule(inst)) {
return nullptr;
}
// Collect the values of the constant parameters.
@@ -661,29 +610,58 @@ Instruction* InstructionFolder::FoldInstructionToConstant(
}
}
- uint32_t result_val = 0;
bool successful = false;
+
// If all parameters are constant, fold the instruction to a constant.
- if (!missing_constants && inst->IsFoldableByFoldScalar()) {
- result_val = FoldScalars(inst->opcode(), constants);
- successful = true;
- }
+ if (inst->IsFoldableByFoldScalar()) {
+ uint32_t result_val = 0;
- if (!successful && inst->IsFoldableByFoldScalar()) {
- successful = FoldIntegerOpToConstant(inst, id_map, &result_val);
- }
+ if (!missing_constants) {
+ result_val = FoldScalars(inst->opcode(), constants);
+ successful = true;
+ }
+
+ if (!successful) {
+ successful = FoldIntegerOpToConstant(inst, id_map, &result_val);
+ }
+
+ if (successful) {
+ const analysis::Constant* result_const =
+ const_mgr->GetConstant(const_mgr->GetType(inst), {result_val});
+ Instruction* folded_inst =
+ const_mgr->GetDefiningInstruction(result_const, inst->type_id());
+ return folded_inst;
+ }
+ } else if (inst->IsFoldableByFoldVector()) {
+ std::vector<uint32_t> result_val;
+
+ if (!missing_constants) {
+ if (Instruction* inst_type =
+ context_->get_def_use_mgr()->GetDef(inst->type_id())) {
+ result_val = FoldVectors(
+ inst->opcode(), inst_type->GetSingleWordInOperand(1), constants);
+ successful = true;
+ }
+ }
- if (successful) {
- const analysis::Constant* result_const =
- const_mgr->GetConstant(const_mgr->GetType(inst), {result_val});
- Instruction* folded_inst =
- const_mgr->GetDefiningInstruction(result_const, inst->type_id());
- return folded_inst;
+ if (successful) {
+ const analysis::Constant* result_const =
+ const_mgr->GetNumericVectorConstantWithWords(
+ const_mgr->GetType(inst)->AsVector(), result_val);
+ Instruction* folded_inst =
+ const_mgr->GetDefiningInstruction(result_const, inst->type_id());
+ return folded_inst;
+ }
}
+
return nullptr;
}
bool InstructionFolder::IsFoldableType(Instruction* type_inst) const {
+ return IsFoldableScalarType(type_inst) || IsFoldableVectorType(type_inst);
+}
+
+bool InstructionFolder::IsFoldableScalarType(Instruction* type_inst) const {
// Support 32-bit integers.
if (type_inst->opcode() == spv::Op::OpTypeInt) {
return type_inst->GetSingleWordInOperand(0) == 32;
@@ -696,6 +674,19 @@ bool InstructionFolder::IsFoldableType(Instruction* type_inst) const {
return false;
}
+bool InstructionFolder::IsFoldableVectorType(Instruction* type_inst) const {
+ // Support vectors with foldable components
+ if (type_inst->opcode() == spv::Op::OpTypeVector) {
+ uint32_t component_type_id = type_inst->GetSingleWordInOperand(0);
+ Instruction* def_component_type =
+ context_->get_def_use_mgr()->GetDef(component_type_id);
+ return def_component_type != nullptr &&
+ IsFoldableScalarType(def_component_type);
+ }
+ // Nothing else yet.
+ return false;
+}
+
bool InstructionFolder::FoldInstruction(Instruction* inst) const {
bool modified = false;
Instruction* folded_inst(inst);
diff --git a/third_party/SPIRV-Tools/source/opt/fold.h b/third_party/SPIRV-Tools/source/opt/fold.h
index 9a131d0df..42da65e4d 100644
--- a/third_party/SPIRV-Tools/source/opt/fold.h
+++ b/third_party/SPIRV-Tools/source/opt/fold.h
@@ -86,6 +86,14 @@ class InstructionFolder {
// result type is |type_inst|.
bool IsFoldableType(Instruction* type_inst) const;
+ // Returns true if |FoldInstructionToConstant| could fold an instruction whose
+ // result type is |type_inst|.
+ bool IsFoldableScalarType(Instruction* type_inst) const;
+
+ // Returns true if |FoldInstructionToConstant| could fold an instruction whose
+ // result type is |type_inst|.
+ bool IsFoldableVectorType(Instruction* type_inst) const;
+
// Tries to fold |inst| to a single constant, when the input ids to |inst|
// have been substituted using |id_map|. Returns a pointer to the OpConstant*
// instruction if successful. If necessary, a new constant instruction is
diff --git a/third_party/SPIRV-Tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp b/third_party/SPIRV-Tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp
index f6d61554a..c568027d2 100644
--- a/third_party/SPIRV-Tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/fold_spec_constant_op_and_composite_pass.cpp
@@ -115,20 +115,9 @@ bool FoldSpecConstantOpAndCompositePass::ProcessOpSpecConstantOp(
"The first in-operand of OpSpecConstantOp instruction must be of "
"SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER type");
- switch (static_cast<spv::Op>(inst->GetSingleWordInOperand(0))) {
- case spv::Op::OpCompositeExtract:
- case spv::Op::OpVectorShuffle:
- case spv::Op::OpCompositeInsert:
- case spv::Op::OpQuantizeToF16:
- folded_inst = FoldWithInstructionFolder(pos);
- break;
- default:
- // TODO: This should use the instruction folder as well, but some folding
- // rules are missing.
-
- // Component-wise operations.
- folded_inst = DoComponentWiseOperation(pos);
- break;
+ folded_inst = FoldWithInstructionFolder(pos);
+ if (!folded_inst) {
+ folded_inst = DoComponentWiseOperation(pos);
}
if (!folded_inst) return false;
@@ -176,8 +165,9 @@ Instruction* FoldSpecConstantOpAndCompositePass::FoldWithInstructionFolder(
Instruction* new_const_inst =
context()->get_instruction_folder().FoldInstructionToConstant(
inst.get(), identity_map);
- assert(new_const_inst != nullptr &&
- "Failed to fold instruction that must be folded.");
+
+ // new_const_inst == null indicates we cannot fold this spec constant
+ if (!new_const_inst) return nullptr;
// Get the instruction before |pos| to insert after. |pos| cannot be the
// first instruction in the list because its type has to come first.
diff --git a/third_party/SPIRV-Tools/source/opt/folding_rules.cpp b/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
index 7730ac1d2..5c68e291c 100644
--- a/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
+++ b/third_party/SPIRV-Tools/source/opt/folding_rules.cpp
@@ -2067,7 +2067,8 @@ FoldingRule FMixFeedingExtract() {
}
// Returns the number of elements in the composite type |type|. Returns 0 if
-// |type| is a scalar value.
+// |type| is a scalar value. Return UINT32_MAX when the size is unknown at
+// compile time.
uint32_t GetNumberOfElements(const analysis::Type* type) {
if (auto* vector_type = type->AsVector()) {
return vector_type->element_count();
@@ -2079,21 +2080,27 @@ uint32_t GetNumberOfElements(const analysis::Type* type) {
return static_cast<uint32_t>(struct_type->element_types().size());
}
if (auto* array_type = type->AsArray()) {
- return array_type->length_info().words[0];
+ if (array_type->length_info().words[0] ==
+ analysis::Array::LengthInfo::kConstant &&
+ array_type->length_info().words.size() == 2) {
+ return array_type->length_info().words[1];
+ }
+ return UINT32_MAX;
}
return 0;
}
// Returns a map with the set of values that were inserted into an object by
// the chain of OpCompositeInsertInstruction starting with |inst|.
-// The map will map the index to the value inserted at that index.
+// The map will map the index to the value inserted at that index. An empty map
+// will be returned if the map could not be properly generated.
std::map<uint32_t, uint32_t> GetInsertedValues(Instruction* inst) {
analysis::DefUseManager* def_use_mgr = inst->context()->get_def_use_mgr();
std::map<uint32_t, uint32_t> values_inserted;
Instruction* current_inst = inst;
while (current_inst->opcode() == spv::Op::OpCompositeInsert) {
if (current_inst->NumInOperands() > inst->NumInOperands()) {
- // This is the catch the case
+ // This is to catch the case
// %2 = OpCompositeInsert %m2x2int %v2int_1_0 %m2x2int_undef 0
// %3 = OpCompositeInsert %m2x2int %int_4 %2 0 0
// %4 = OpCompositeInsert %m2x2int %v2int_2_3 %3 1
@@ -2884,8 +2891,12 @@ FoldingRule UpdateImageOperands() {
"Offset and ConstOffset may not be used together");
if (offset_operand_index < inst->NumOperands()) {
if (constants[offset_operand_index]) {
- image_operands =
- image_operands | uint32_t(spv::ImageOperandsMask::ConstOffset);
+ if (constants[offset_operand_index]->IsZero()) {
+ inst->RemoveInOperand(offset_operand_index);
+ } else {
+ image_operands = image_operands |
+ uint32_t(spv::ImageOperandsMask::ConstOffset);
+ }
image_operands =
image_operands & ~uint32_t(spv::ImageOperandsMask::Offset);
inst->SetInOperand(operand_index, {image_operands});
diff --git a/third_party/SPIRV-Tools/source/opt/graphics_robust_access_pass.cpp b/third_party/SPIRV-Tools/source/opt/graphics_robust_access_pass.cpp
index 8fff8a032..e765c3976 100644
--- a/third_party/SPIRV-Tools/source/opt/graphics_robust_access_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/graphics_robust_access_pass.cpp
@@ -573,9 +573,9 @@ uint32_t GraphicsRobustAccessPass::GetGlslInsts() {
context()->module()->AddExtInstImport(std::move(import_inst));
module_status_.modified = true;
context()->AnalyzeDefUse(inst);
- // Reanalyze the feature list, since we added an extended instruction
- // set improt.
- context()->get_feature_mgr()->Analyze(context()->module());
+ // Invalidates the feature manager, since we added an extended instruction
+ // set import.
+ context()->ResetFeatureManager();
}
}
return module_status_.glsl_insts_id;
diff --git a/third_party/SPIRV-Tools/source/opt/inline_pass.cpp b/third_party/SPIRV-Tools/source/opt/inline_pass.cpp
index 3f160b24c..318643341 100644
--- a/third_party/SPIRV-Tools/source/opt/inline_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inline_pass.cpp
@@ -213,6 +213,19 @@ uint32_t InlinePass::CreateReturnVar(
{(uint32_t)spv::StorageClass::Function}}}));
new_vars->push_back(std::move(var_inst));
get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId);
+
+ // Decorate the return var with AliasedPointer if the storage class of the
+ // pointee type is PhysicalStorageBuffer.
+ auto const pointee_type =
+ type_mgr->GetType(returnVarTypeId)->AsPointer()->pointee_type();
+ if (pointee_type->AsPointer() != nullptr) {
+ if (pointee_type->AsPointer()->storage_class() ==
+ spv::StorageClass::PhysicalStorageBuffer) {
+ get_decoration_mgr()->AddDecoration(
+ returnVarId, uint32_t(spv::Decoration::AliasedPointer));
+ }
+ }
+
return returnVarId;
}
diff --git a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
index e8c412ffe..8e7d4f83e 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.cpp
@@ -31,532 +31,88 @@ constexpr int kSpvLoadPtrIdInIdx = 0;
constexpr int kSpvAccessChainBaseIdInIdx = 0;
constexpr int kSpvAccessChainIndex0IdInIdx = 1;
constexpr int kSpvTypeArrayTypeIdInIdx = 0;
-constexpr int kSpvTypeArrayLengthIdInIdx = 1;
-constexpr int kSpvConstantValueInIdx = 0;
constexpr int kSpvVariableStorageClassInIdx = 0;
constexpr int kSpvTypePtrTypeIdInIdx = 1;
constexpr int kSpvTypeImageDim = 1;
constexpr int kSpvTypeImageDepth = 2;
constexpr int kSpvTypeImageArrayed = 3;
constexpr int kSpvTypeImageMS = 4;
-constexpr int kSpvTypeImageSampled = 5;
} // namespace
-void InstBindlessCheckPass::SetupInputBufferIds() {
- if (input_buffer_id_ != 0) {
- return;
- }
- AddStorageBufferExt();
- if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) {
- context()->AddExtension("SPV_KHR_physical_storage_buffer");
- }
- context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses);
- Instruction* memory_model = get_module()->GetMemoryModel();
- // TODO should this be just Physical64?
- memory_model->SetInOperand(
- 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)});
-
- analysis::DecorationManager* deco_mgr = get_decoration_mgr();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- constexpr uint32_t width = 32u;
-
- // declare the DescriptorSetData struct
- analysis::Struct* desc_set_struct =
- GetStruct({type_mgr->GetUIntType(), GetUintRuntimeArrayType(width)});
- desc_set_type_id_ = type_mgr->GetTypeInstruction(desc_set_struct);
- // By the Vulkan spec, a pre-existing struct containing a RuntimeArray
- // must be a block, and will therefore be decorated with Block. Therefore
- // the undecorated type returned here will not be pre-existing and can
- // safely be decorated. Since this type is now decorated, it is out of
- // sync with the TypeManager and therefore the TypeManager must be
- // invalidated after this pass.
- assert(context()->get_def_use_mgr()->NumUses(desc_set_type_id_) == 0 &&
- "used struct type returned");
- deco_mgr->AddDecoration(desc_set_type_id_, uint32_t(spv::Decoration::Block));
- deco_mgr->AddMemberDecoration(desc_set_type_id_, 0,
- uint32_t(spv::Decoration::Offset), 0);
- deco_mgr->AddMemberDecoration(desc_set_type_id_, 1,
- uint32_t(spv::Decoration::Offset), 4);
- context()->AddDebug2Inst(
- NewGlobalName(desc_set_type_id_, "DescriptorSetData"));
- context()->AddDebug2Inst(NewMemberName(desc_set_type_id_, 0, "num_bindings"));
- context()->AddDebug2Inst(NewMemberName(desc_set_type_id_, 1, "data"));
-
- // declare buffer address reference to DescriptorSetData
- desc_set_ptr_id_ = type_mgr->FindPointerToType(
- desc_set_type_id_, spv::StorageClass::PhysicalStorageBuffer);
- // runtime array of buffer addresses
- analysis::Type* rarr_ty = GetArray(type_mgr->GetType(desc_set_ptr_id_),
- kDebugInputBindlessMaxDescSets);
- deco_mgr->AddDecorationVal(type_mgr->GetId(rarr_ty),
- uint32_t(spv::Decoration::ArrayStride), 8u);
-
- // declare the InputBuffer type, a struct wrapper around the runtime array
- analysis::Struct* input_buffer_struct = GetStruct({rarr_ty});
- input_buffer_struct_id_ = type_mgr->GetTypeInstruction(input_buffer_struct);
- deco_mgr->AddDecoration(input_buffer_struct_id_,
- uint32_t(spv::Decoration::Block));
- deco_mgr->AddMemberDecoration(input_buffer_struct_id_, 0,
- uint32_t(spv::Decoration::Offset), 0);
- context()->AddDebug2Inst(
- NewGlobalName(input_buffer_struct_id_, "InputBuffer"));
- context()->AddDebug2Inst(
- NewMemberName(input_buffer_struct_id_, 0, "desc_sets"));
-
- input_buffer_ptr_id_ = type_mgr->FindPointerToType(
- input_buffer_struct_id_, spv::StorageClass::StorageBuffer);
-
- // declare the input_buffer global variable
- input_buffer_id_ = TakeNextId();
-
- const std::vector<Operand> var_operands = {
- {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::StorageClass::StorageBuffer)}},
- };
- auto new_var_op = spvtools::MakeUnique<Instruction>(
- context(), spv::Op::OpVariable, input_buffer_ptr_id_, input_buffer_id_,
- var_operands);
-
- context()->AddGlobalValue(std::move(new_var_op));
- context()->AddDebug2Inst(NewGlobalName(input_buffer_id_, "input_buffer"));
- deco_mgr->AddDecorationVal(
- input_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_);
- deco_mgr->AddDecorationVal(input_buffer_id_,
- uint32_t(spv::Decoration::Binding),
- GetInputBufferBinding());
- if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
- // Add the new buffer to all entry points.
- for (auto& entry : get_module()->entry_points()) {
- entry.AddOperand({SPV_OPERAND_TYPE_ID, {input_buffer_id_}});
- context()->AnalyzeUses(&entry);
- }
- }
-}
-
+// This is a stub function for use with Import linkage
// clang-format off
// GLSL:
-// uint inst_bindless_read_binding_length(uint desc_set_idx, uint binding_idx)
-// {
-// if (desc_set_idx >= inst_bindless_input_buffer.desc_sets.length()) {
-// return 0;
-// }
-//
-// DescriptorSetData set_data = inst_bindless_input_buffer.desc_sets[desc_set_idx];
-// uvec2 ptr_as_vec = uvec2(set_data);
-// if ((ptr_as_vec.x == 0u) && (_ptr_as_vec.y == 0u))
-// {
-// return 0u;
-// }
-// uint num_bindings = set_data.num_bindings;
-// if (binding_idx >= num_bindings) {
-// return 0;
-// }
-// return set_data.data[binding_idx];
-// }
+//bool inst_bindless_check_desc(const uint shader_id, const uint inst_num, const uvec4 stage_info, const uint desc_set,
+// const uint binding, const uint desc_index, const uint byte_offset) {
+//}
// clang-format on
-uint32_t InstBindlessCheckPass::GenDebugReadLengthFunctionId() {
- if (read_length_func_id_ != 0) {
- return read_length_func_id_;
+uint32_t InstBindlessCheckPass::GenDescCheckFunctionId() {
+ enum {
+ kShaderId = 0,
+ kInstructionIndex = 1,
+ kStageInfo = 2,
+ kDescSet = 3,
+ kDescBinding = 4,
+ kDescIndex = 5,
+ kByteOffset = 6,
+ kNumArgs
+ };
+ if (check_desc_func_id_ != 0) {
+ return check_desc_func_id_;
}
- SetupInputBufferIds();
- const analysis::Integer* uint_type = GetInteger(32, false);
- const std::vector<const analysis::Type*> param_types(2, uint_type);
-
- const uint32_t func_id = TakeNextId();
- std::unique_ptr<Function> func =
- StartFunction(func_id, uint_type, param_types);
-
- const std::vector<uint32_t> param_ids = AddParameters(*func, param_types);
-
- // Create block
- auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
- InstructionBuilder builder(
- context(), new_blk_ptr.get(),
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- Instruction* inst;
-
- inst = builder.AddBinaryOp(
- GetBoolId(), spv::Op::OpUGreaterThanEqual, param_ids[0],
- builder.GetUintConstantId(kDebugInputBindlessMaxDescSets));
- const uint32_t desc_cmp_id = inst->result_id();
-
- uint32_t error_blk_id = TakeNextId();
- uint32_t merge_blk_id = TakeNextId();
- std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
- std::unique_ptr<Instruction> error_label(NewLabel(error_blk_id));
- (void)builder.AddConditionalBranch(desc_cmp_id, error_blk_id, merge_blk_id,
- merge_blk_id);
-
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // check descriptor set table entry is non-null
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
analysis::TypeManager* type_mgr = context()->get_type_mgr();
- const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
- desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
-
- inst = builder.AddAccessChain(desc_set_ptr_ptr, input_buffer_id_,
- {builder.GetUintConstantId(0), param_ids[0]});
- const uint32_t set_access_chain_id = inst->result_id();
-
- inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
- const uint32_t desc_set_ptr_id = inst->result_id();
-
- inst =
- builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast, desc_set_ptr_id);
- const uint32_t ptr_as_uvec_id = inst->result_id();
-
- inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
- const uint32_t uvec_x = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x,
- builder.GetUintConstantId(0));
- const uint32_t x_is_zero_id = inst->result_id();
-
- inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
- const uint32_t uvec_y = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y,
- builder.GetUintConstantId(0));
- const uint32_t y_is_zero_id = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
- y_is_zero_id);
- const uint32_t is_null_id = inst->result_id();
-
- error_blk_id = TakeNextId();
- merge_blk_id = TakeNextId();
- merge_label = NewLabel(merge_blk_id);
- error_label = NewLabel(error_blk_id);
- (void)builder.AddConditionalBranch(is_null_id, error_blk_id, merge_blk_id,
- merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // check binding is in range
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- const uint32_t uint_ptr = type_mgr->FindPointerToType(
- GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
-
- inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {builder.GetUintConstantId(0)});
- const uint32_t binding_access_chain_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
- const uint32_t num_bindings_id = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
- param_ids[1], num_bindings_id);
- const uint32_t bindings_cmp_id = inst->result_id();
-
- error_blk_id = TakeNextId();
- merge_blk_id = TakeNextId();
- merge_label = NewLabel(merge_blk_id);
- error_label = NewLabel(error_blk_id);
- (void)builder.AddConditionalBranch(bindings_cmp_id, error_blk_id,
- merge_blk_id, merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // read binding length
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {{builder.GetUintConstantId(1), param_ids[1]}});
- const uint32_t length_ac_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
- const uint32_t length_id = inst->result_id();
-
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, length_id);
-
- func->AddBasicBlock(std::move(new_blk_ptr));
- func->SetFunctionEnd(EndFunction());
-
- context()->AddFunction(std::move(func));
- context()->AddDebug2Inst(NewGlobalName(func_id, "read_binding_length"));
-
- read_length_func_id_ = func_id;
- // Make sure this function doesn't get processed by
- // InstrumentPass::InstProcessCallTreeFromRoots()
- param2output_func_id_[2] = func_id;
- return read_length_func_id_;
-}
-
-// clang-format off
-// GLSL:
-// result = inst_bindless_read_binding_length(desc_set_id, binding_id);
-// clang-format on
-uint32_t InstBindlessCheckPass::GenDebugReadLength(
- uint32_t var_id, InstructionBuilder* builder) {
- const uint32_t func_id = GenDebugReadLengthFunctionId();
-
- const std::vector<uint32_t> args = {
- builder->GetUintConstantId(var2desc_set_[var_id]),
- builder->GetUintConstantId(var2binding_[var_id]),
- };
- return GenReadFunctionCall(func_id, args, builder);
-}
-
-// clang-format off
-// GLSL:
-// uint inst_bindless_read_desc_init(uint desc_set_idx, uint binding_idx, uint desc_idx)
-// {
-// if (desc_set_idx >= uint(inst_bindless_input_buffer.desc_sets.length()))
-// {
-// return 0u;
-// }
-// DescriptorSetData set_data = inst_bindless_input_buffer.desc_sets[desc_set_idx];
-// uvec2 ptr_as_vec = uvec2(set_data)
-// if ((ptr_as_vec .x == 0u) && (ptr_as_vec.y == 0u))
-// {
-// return 0u;
-// }
-// if (binding_idx >= set_data.num_bindings)
-// {
-// return 0u;
-// }
-// if (desc_idx >= set_data.data[binding_idx])
-// {
-// return 0u;
-// }
-// uint desc_records_start = set_data.data[set_data.num_bindings + binding_idx];
-// return set_data.data[desc_records_start + desc_idx];
-// }
-// clang-format on
-uint32_t InstBindlessCheckPass::GenDebugReadInitFunctionId() {
- if (read_init_func_id_ != 0) {
- return read_init_func_id_;
- }
- SetupInputBufferIds();
const analysis::Integer* uint_type = GetInteger(32, false);
- const std::vector<const analysis::Type*> param_types(3, uint_type);
+ const analysis::Vector v4uint(uint_type, 4);
+ const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint);
+ std::vector<const analysis::Type*> param_types(kNumArgs, uint_type);
+ param_types[2] = v4uint_type;
const uint32_t func_id = TakeNextId();
std::unique_ptr<Function> func =
- StartFunction(func_id, uint_type, param_types);
-
- const std::vector<uint32_t> param_ids = AddParameters(*func, param_types);
-
- // Create block
- auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
- InstructionBuilder builder(
- context(), new_blk_ptr.get(),
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- Instruction* inst;
-
- inst = builder.AddBinaryOp(
- GetBoolId(), spv::Op::OpUGreaterThanEqual, param_ids[0],
- builder.GetUintConstantId(kDebugInputBindlessMaxDescSets));
- const uint32_t desc_cmp_id = inst->result_id();
-
- uint32_t error_blk_id = TakeNextId();
- uint32_t merge_blk_id = TakeNextId();
- std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
- std::unique_ptr<Instruction> error_label(NewLabel(error_blk_id));
- (void)builder.AddConditionalBranch(desc_cmp_id, error_blk_id, merge_blk_id,
- merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // check descriptor set table entry is non-null
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- const uint32_t desc_set_ptr_ptr = type_mgr->FindPointerToType(
- desc_set_ptr_id_, spv::StorageClass::StorageBuffer);
-
- inst = builder.AddAccessChain(desc_set_ptr_ptr, input_buffer_id_,
- {builder.GetUintConstantId(0), param_ids[0]});
- const uint32_t set_access_chain_id = inst->result_id();
-
- inst = builder.AddLoad(desc_set_ptr_id_, set_access_chain_id);
- const uint32_t desc_set_ptr_id = inst->result_id();
-
- inst =
- builder.AddUnaryOp(GetVecUintId(2), spv::Op::OpBitcast, desc_set_ptr_id);
- const uint32_t ptr_as_uvec_id = inst->result_id();
-
- inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {0});
- const uint32_t uvec_x = inst->result_id();
+ StartFunction(func_id, type_mgr->GetBoolType(), param_types);
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_x,
- builder.GetUintConstantId(0));
- const uint32_t x_is_zero_id = inst->result_id();
-
- inst = builder.AddCompositeExtract(GetUintId(), ptr_as_uvec_id, {1});
- const uint32_t uvec_y = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpIEqual, uvec_y,
- builder.GetUintConstantId(0));
- const uint32_t y_is_zero_id = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpLogicalAnd, x_is_zero_id,
- y_is_zero_id);
- const uint32_t is_null_id = inst->result_id();
-
- error_blk_id = TakeNextId();
- merge_blk_id = TakeNextId();
- merge_label = NewLabel(merge_blk_id);
- error_label = NewLabel(error_blk_id);
- (void)builder.AddConditionalBranch(is_null_id, error_blk_id, merge_blk_id,
- merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // check binding is in range
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- const uint32_t uint_ptr = type_mgr->FindPointerToType(
- GetUintId(), spv::StorageClass::PhysicalStorageBuffer);
-
- inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {builder.GetUintConstantId(0)});
- const uint32_t binding_access_chain_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), binding_access_chain_id, 8);
- const uint32_t num_bindings_id = inst->result_id();
-
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
- param_ids[1], num_bindings_id);
- const uint32_t bindings_cmp_id = inst->result_id();
-
- error_blk_id = TakeNextId();
- merge_blk_id = TakeNextId();
- merge_label = NewLabel(merge_blk_id);
- error_label = NewLabel(error_blk_id);
- (void)builder.AddConditionalBranch(bindings_cmp_id, error_blk_id,
- merge_blk_id, merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
- // error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // read binding length
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- inst = builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {{builder.GetUintConstantId(1), param_ids[1]}});
- const uint32_t length_ac_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), length_ac_id, sizeof(uint32_t));
- const uint32_t length_id = inst->result_id();
-
- // Check descriptor index in bounds
- inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThanEqual,
- param_ids[2], length_id);
- const uint32_t desc_idx_range_id = inst->result_id();
-
- error_blk_id = TakeNextId();
- merge_blk_id = TakeNextId();
- merge_label = NewLabel(merge_blk_id);
- error_label = NewLabel(error_blk_id);
- (void)builder.AddConditionalBranch(desc_idx_range_id, error_blk_id,
- merge_blk_id, merge_blk_id);
- func->AddBasicBlock(std::move(new_blk_ptr));
- // Error return
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(error_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- builder.GetUintConstantId(0));
- func->AddBasicBlock(std::move(new_blk_ptr));
-
- // Read descriptor init status
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
-
- inst = builder.AddIAdd(GetUintId(), num_bindings_id, param_ids[1]);
- const uint32_t state_offset_id = inst->result_id();
-
- inst =
- builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {{builder.GetUintConstantId(1), state_offset_id}});
- const uint32_t state_start_ac_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), state_start_ac_id, sizeof(uint32_t));
- const uint32_t state_start_id = inst->result_id();
-
- inst = builder.AddIAdd(GetUintId(), state_start_id, param_ids[2]);
- const uint32_t state_entry_id = inst->result_id();
-
- // Note: length starts from the beginning of the buffer, not the beginning of
- // the data array
- inst =
- builder.AddAccessChain(uint_ptr, desc_set_ptr_id,
- {{builder.GetUintConstantId(1), state_entry_id}});
- const uint32_t init_ac_id = inst->result_id();
-
- inst = builder.AddLoad(GetUintId(), init_ac_id, sizeof(uint32_t));
- const uint32_t init_status_id = inst->result_id();
-
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, init_status_id);
-
- func->AddBasicBlock(std::move(new_blk_ptr));
func->SetFunctionEnd(EndFunction());
- context()->AddFunction(std::move(func));
- context()->AddDebug2Inst(NewGlobalName(func_id, "read_desc_init"));
+ static const std::string func_name{"inst_bindless_check_desc"};
+ context()->AddFunctionDeclaration(std::move(func));
+ context()->AddDebug2Inst(NewName(func_id, func_name));
+ std::vector<Operand> operands{
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+ {uint32_t(spv::Decoration::LinkageAttributes)}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING,
+ utils::MakeVector(func_name.c_str())},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE,
+ {uint32_t(spv::LinkageType::Import)}},
+ };
+ get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands);
- read_init_func_id_ = func_id;
+ check_desc_func_id_ = func_id;
// Make sure function doesn't get processed by
// InstrumentPass::InstProcessCallTreeFromRoots()
param2output_func_id_[3] = func_id;
- return read_init_func_id_;
+ return check_desc_func_id_;
}
// clang-format off
// GLSL:
-// result = inst_bindless_read_desc_init(desc_set_id, binding_id, desc_idx_id);
+// result = inst_bindless_check_desc(shader_id, inst_idx, stage_info, desc_set, binding, desc_idx, offset);
//
// clang-format on
-uint32_t InstBindlessCheckPass::GenDebugReadInit(uint32_t var_id,
- uint32_t desc_idx_id,
- InstructionBuilder* builder) {
- const uint32_t func_id = GenDebugReadInitFunctionId();
+uint32_t InstBindlessCheckPass::GenDescCheckCall(
+ uint32_t inst_idx, uint32_t stage_idx, uint32_t var_id,
+ uint32_t desc_idx_id, uint32_t offset_id, InstructionBuilder* builder) {
+ const uint32_t func_id = GenDescCheckFunctionId();
const std::vector<uint32_t> args = {
+ builder->GetUintConstantId(shader_id_),
+ builder->GetUintConstantId(inst_idx),
+ GenStageInfo(stage_idx, builder),
builder->GetUintConstantId(var2desc_set_[var_id]),
builder->GetUintConstantId(var2binding_[var_id]),
- GenUintCastCode(desc_idx_id, builder)};
- return GenReadFunctionCall(func_id, args, builder);
+ GenUintCastCode(desc_idx_id, builder),
+ offset_id};
+ return GenReadFunctionCall(GetBoolId(), func_id, args, builder);
}
uint32_t InstBindlessCheckPass::CloneOriginalImage(
@@ -1017,8 +573,7 @@ uint32_t InstBindlessCheckPass::GenLastByteIdx(RefAnalysis* ref,
}
void InstBindlessCheckPass::GenCheckCode(
- uint32_t check_id, uint32_t error_id, uint32_t offset_id,
- uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref,
+ uint32_t check_id, RefAnalysis* ref,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
BasicBlock* back_blk_ptr = &*new_blocks->back();
InstructionBuilder builder(
@@ -1047,30 +602,7 @@ void InstBindlessCheckPass::GenCheckCode(
// Gen invalid block
new_blk_ptr.reset(new BasicBlock(std::move(invalid_label)));
builder.SetInsertPoint(&*new_blk_ptr);
- const uint32_t u_set_id = builder.GetUintConstantId(ref->set);
- const uint32_t u_binding_id = builder.GetUintConstantId(ref->binding);
- const uint32_t u_index_id = GenUintCastCode(ref->desc_idx_id, &builder);
- const uint32_t u_length_id = GenUintCastCode(length_id, &builder);
- if (offset_id != 0) {
- const uint32_t u_offset_id = GenUintCastCode(offset_id, &builder);
- // Buffer OOB
- GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
- {error_id, u_set_id, u_binding_id, u_index_id,
- u_offset_id, u_length_id},
- &builder);
- } else if (buffer_bounds_enabled_ || texel_buffer_enabled_) {
- // Uninitialized Descriptor - Return additional unused zero so all error
- // modes will use same debug stream write function
- GenDebugStreamWrite(uid2offset_[ref->ref_inst->unique_id()], stage_idx,
- {error_id, u_set_id, u_binding_id, u_index_id,
- u_length_id, builder.GetUintConstantId(0)},
- &builder);
- } else {
- // Uninitialized Descriptor - Normal error return
- GenDebugStreamWrite(
- uid2offset_[ref->ref_inst->unique_id()], stage_idx,
- {error_id, u_set_id, u_binding_id, u_index_id, u_length_id}, &builder);
- }
+
// Generate a ConstantNull, converting to uint64 if the type cannot be a null.
if (new_ref_id != 0) {
analysis::TypeManager* type_mgr = context()->get_type_mgr();
@@ -1106,77 +638,42 @@ void InstBindlessCheckPass::GenCheckCode(
context()->KillInst(ref->ref_inst);
}
-void InstBindlessCheckPass::GenDescIdxCheckCode(
+void InstBindlessCheckPass::GenDescCheckCode(
BasicBlock::iterator ref_inst_itr,
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- // Look for reference through indexed descriptor. If found, analyze and
- // save components. If not, return.
+ // Look for reference through descriptor. If not, return.
RefAnalysis ref;
if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return;
- Instruction* ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id);
- if (ptr_inst->opcode() != spv::Op::OpAccessChain) return;
- // If index and bound both compile-time constants and index < bound,
- // return without changing
- Instruction* var_inst = get_def_use_mgr()->GetDef(ref.var_id);
- Instruction* desc_type_inst = GetPointeeTypeInst(var_inst);
- uint32_t length_id = 0;
- if (desc_type_inst->opcode() == spv::Op::OpTypeArray) {
- length_id =
- desc_type_inst->GetSingleWordInOperand(kSpvTypeArrayLengthIdInIdx);
- Instruction* index_inst = get_def_use_mgr()->GetDef(ref.desc_idx_id);
- Instruction* length_inst = get_def_use_mgr()->GetDef(length_id);
- if (index_inst->opcode() == spv::Op::OpConstant &&
- length_inst->opcode() == spv::Op::OpConstant &&
- index_inst->GetSingleWordInOperand(kSpvConstantValueInIdx) <
- length_inst->GetSingleWordInOperand(kSpvConstantValueInIdx))
- return;
- } else if (!desc_idx_enabled_ ||
- desc_type_inst->opcode() != spv::Op::OpTypeRuntimeArray) {
- return;
- }
- // Move original block's preceding instructions into first new block
std::unique_ptr<BasicBlock> new_blk_ptr;
+ // Move original block's preceding instructions into first new block
MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr);
InstructionBuilder builder(
context(), &*new_blk_ptr,
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
new_blocks->push_back(std::move(new_blk_ptr));
- uint32_t error_id = builder.GetUintConstantId(kInstErrorBindlessBounds);
- // If length id not yet set, descriptor array is runtime size so
- // generate load of length from stage's debug input buffer.
- if (length_id == 0) {
- assert(desc_type_inst->opcode() == spv::Op::OpTypeRuntimeArray &&
- "unexpected bindless type");
- length_id = GenDebugReadLength(ref.var_id, &builder);
- }
- // Generate full runtime bounds test code with true branch
- // being full reference and false branch being debug output and zero
- // for the referenced value.
- uint32_t desc_idx_32b_id = Gen32BitCvtCode(ref.desc_idx_id, &builder);
- uint32_t length_32b_id = Gen32BitCvtCode(length_id, &builder);
- Instruction* ult_inst = builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan,
- desc_idx_32b_id, length_32b_id);
- ref.desc_idx_id = desc_idx_32b_id;
- GenCheckCode(ult_inst->result_id(), error_id, 0u, length_id, stage_idx, &ref,
- new_blocks);
- // Move original block's remaining code into remainder/merge block and add
- // to new blocks
- BasicBlock* back_blk_ptr = &*new_blocks->back();
- MovePostludeCode(ref_block_itr, back_blk_ptr);
-}
-
-void InstBindlessCheckPass::GenDescInitCheckCode(
- BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- // Look for reference through descriptor. If not, return.
- RefAnalysis ref;
- if (!AnalyzeDescriptorReference(&*ref_inst_itr, &ref)) return;
// Determine if we can only do initialization check
- bool init_check = false;
- if (ref.desc_load_id != 0 || !buffer_bounds_enabled_) {
- init_check = true;
+ uint32_t ref_id = builder.GetUintConstantId(0u);
+ spv::Op op = ref.ref_inst->opcode();
+ if (ref.desc_load_id != 0) {
+ uint32_t num_in_oprnds = ref.ref_inst->NumInOperands();
+ if ((op == spv::Op::OpImageRead && num_in_oprnds == 2) ||
+ (op == spv::Op::OpImageFetch && num_in_oprnds == 2) ||
+ (op == spv::Op::OpImageWrite && num_in_oprnds == 3)) {
+ Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id);
+ uint32_t image_ty_id = image_inst->type_id();
+ Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id);
+ if (spv::Dim(image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim)) ==
+ spv::Dim::Buffer) {
+ if ((image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) == 0) &&
+ (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) ==
+ 0) &&
+ (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) == 0)) {
+ ref_id = GenUintCastCode(ref.ref_inst->GetSingleWordInOperand(1),
+ &builder);
+ }
+ }
+ }
} else {
// For now, only do bounds check for non-aggregate types. Otherwise
// just do descriptor initialization check.
@@ -1184,106 +681,24 @@ void InstBindlessCheckPass::GenDescInitCheckCode(
Instruction* ref_ptr_inst = get_def_use_mgr()->GetDef(ref.ptr_id);
Instruction* pte_type_inst = GetPointeeTypeInst(ref_ptr_inst);
spv::Op pte_type_op = pte_type_inst->opcode();
- if (pte_type_op == spv::Op::OpTypeArray ||
- pte_type_op == spv::Op::OpTypeRuntimeArray ||
- pte_type_op == spv::Op::OpTypeStruct)
- init_check = true;
+ if (pte_type_op != spv::Op::OpTypeArray &&
+ pte_type_op != spv::Op::OpTypeRuntimeArray &&
+ pte_type_op != spv::Op::OpTypeStruct) {
+ ref_id = GenLastByteIdx(&ref, &builder);
+ }
}
- // If initialization check and not enabled, return
- if (init_check && !desc_init_enabled_) return;
- // Move original block's preceding instructions into first new block
- std::unique_ptr<BasicBlock> new_blk_ptr;
- MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr);
- InstructionBuilder builder(
- context(), &*new_blk_ptr,
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- new_blocks->push_back(std::move(new_blk_ptr));
- // If initialization check, use reference value of zero.
- // Else use the index of the last byte referenced.
- uint32_t ref_id = init_check ? builder.GetUintConstantId(0u)
- : GenLastByteIdx(&ref, &builder);
// Read initialization/bounds from debug input buffer. If index id not yet
// set, binding is single descriptor, so set index to constant 0.
if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u);
- uint32_t init_id = GenDebugReadInit(ref.var_id, ref.desc_idx_id, &builder);
- // Generate runtime initialization/bounds test code with true branch
- // being full reference and false branch being debug output and zero
- // for the referenced value.
- Instruction* ult_inst =
- builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan, ref_id, init_id);
- uint32_t error =
- init_check
- ? kInstErrorBindlessUninit
- : (spv::StorageClass(ref.strg_class) == spv::StorageClass::Uniform
- ? kInstErrorBuffOOBUniform
- : kInstErrorBuffOOBStorage);
- uint32_t error_id = builder.GetUintConstantId(error);
- GenCheckCode(ult_inst->result_id(), error_id, init_check ? 0 : ref_id,
- init_check ? builder.GetUintConstantId(0u) : init_id, stage_idx,
- &ref, new_blocks);
- // Move original block's remaining code into remainder/merge block and add
- // to new blocks
- BasicBlock* back_blk_ptr = &*new_blocks->back();
- MovePostludeCode(ref_block_itr, back_blk_ptr);
-}
+ uint32_t check_id =
+ GenDescCheckCall(ref.ref_inst->unique_id(), stage_idx, ref.var_id,
+ ref.desc_idx_id, ref_id, &builder);
-void InstBindlessCheckPass::GenTexBuffCheckCode(
- BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- // Only process OpImageRead and OpImageWrite with no optional operands
- Instruction* ref_inst = &*ref_inst_itr;
- spv::Op op = ref_inst->opcode();
- uint32_t num_in_oprnds = ref_inst->NumInOperands();
- if (!((op == spv::Op::OpImageRead && num_in_oprnds == 2) ||
- (op == spv::Op::OpImageFetch && num_in_oprnds == 2) ||
- (op == spv::Op::OpImageWrite && num_in_oprnds == 3)))
- return;
- // Pull components from descriptor reference
- RefAnalysis ref;
- if (!AnalyzeDescriptorReference(ref_inst, &ref)) return;
- // Only process if image is texel buffer
- Instruction* image_inst = get_def_use_mgr()->GetDef(ref.image_id);
- uint32_t image_ty_id = image_inst->type_id();
- Instruction* image_ty_inst = get_def_use_mgr()->GetDef(image_ty_id);
- if (spv::Dim(image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDim)) !=
- spv::Dim::Buffer) {
- return;
- }
- if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageDepth) != 0) return;
- if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageArrayed) != 0) return;
- if (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageMS) != 0) return;
- // Enable ImageQuery Capability if not yet enabled
- context()->AddCapability(spv::Capability::ImageQuery);
- // Move original block's preceding instructions into first new block
- std::unique_ptr<BasicBlock> new_blk_ptr;
- MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr);
- InstructionBuilder builder(
- context(), &*new_blk_ptr,
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- new_blocks->push_back(std::move(new_blk_ptr));
- // Get texel coordinate
- uint32_t coord_id =
- GenUintCastCode(ref_inst->GetSingleWordInOperand(1), &builder);
- // If index id not yet set, binding is single descriptor, so set index to
- // constant 0.
- if (ref.desc_idx_id == 0) ref.desc_idx_id = builder.GetUintConstantId(0u);
- // Get texel buffer size.
- Instruction* size_inst =
- builder.AddUnaryOp(GetUintId(), spv::Op::OpImageQuerySize, ref.image_id);
- uint32_t size_id = size_inst->result_id();
// Generate runtime initialization/bounds test code with true branch
- // being full reference and false branch being debug output and zero
+ // being full reference and false branch being zero
// for the referenced value.
- Instruction* ult_inst =
- builder.AddBinaryOp(GetBoolId(), spv::Op::OpULessThan, coord_id, size_id);
- uint32_t error =
- (image_ty_inst->GetSingleWordInOperand(kSpvTypeImageSampled) == 2)
- ? kInstErrorBuffOOBStorageTexel
- : kInstErrorBuffOOBUniformTexel;
- uint32_t error_id = builder.GetUintConstantId(error);
- GenCheckCode(ult_inst->result_id(), error_id, coord_id, size_id, stage_idx,
- &ref, new_blocks);
+ GenCheckCode(check_id, &ref, new_blocks);
+
// Move original block's remaining code into remainder/merge block and add
// to new blocks
BasicBlock* back_blk_ptr = &*new_blocks->back();
@@ -1293,59 +708,48 @@ void InstBindlessCheckPass::GenTexBuffCheckCode(
void InstBindlessCheckPass::InitializeInstBindlessCheck() {
// Initialize base class
InitializeInstrument();
- // If runtime array length support or buffer bounds checking are enabled,
- // create variable mappings. Length support is always enabled if descriptor
- // init check is enabled.
- if (desc_idx_enabled_ || buffer_bounds_enabled_ || texel_buffer_enabled_)
- for (auto& anno : get_module()->annotations())
- if (anno.opcode() == spv::Op::OpDecorate) {
- if (spv::Decoration(anno.GetSingleWordInOperand(1u)) ==
- spv::Decoration::DescriptorSet) {
- var2desc_set_[anno.GetSingleWordInOperand(0u)] =
- anno.GetSingleWordInOperand(2u);
- } else if (spv::Decoration(anno.GetSingleWordInOperand(1u)) ==
- spv::Decoration::Binding) {
- var2binding_[anno.GetSingleWordInOperand(0u)] =
- anno.GetSingleWordInOperand(2u);
- }
+ for (auto& anno : get_module()->annotations()) {
+ if (anno.opcode() == spv::Op::OpDecorate) {
+ if (spv::Decoration(anno.GetSingleWordInOperand(1u)) ==
+ spv::Decoration::DescriptorSet) {
+ var2desc_set_[anno.GetSingleWordInOperand(0u)] =
+ anno.GetSingleWordInOperand(2u);
+ } else if (spv::Decoration(anno.GetSingleWordInOperand(1u)) ==
+ spv::Decoration::Binding) {
+ var2binding_[anno.GetSingleWordInOperand(0u)] =
+ anno.GetSingleWordInOperand(2u);
}
+ }
+ }
}
Pass::Status InstBindlessCheckPass::ProcessImpl() {
- // Perform bindless bounds check on each entry point function in module
+ // The memory model and linkage must always be updated for spirv-link to work
+ // correctly.
+ AddStorageBufferExt();
+ if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) {
+ context()->AddExtension("SPV_KHR_physical_storage_buffer");
+ }
+
+ context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses);
+ Instruction* memory_model = get_module()->GetMemoryModel();
+ memory_model->SetInOperand(
+ 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)});
+
+ context()->AddCapability(spv::Capability::Linkage);
+
InstProcessFunction pfn =
[this](BasicBlock::iterator ref_inst_itr,
UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- return GenDescIdxCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
- new_blocks);
+ return GenDescCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
+ new_blocks);
};
- bool modified = InstProcessEntryPointCallTree(pfn);
- if (desc_init_enabled_ || buffer_bounds_enabled_) {
- // Perform descriptor initialization and/or buffer bounds check on each
- // entry point function in module
- pfn = [this](BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr,
- uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- return GenDescInitCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
- new_blocks);
- };
- modified |= InstProcessEntryPointCallTree(pfn);
- }
- if (texel_buffer_enabled_) {
- // Perform texel buffer bounds check on each entry point function in
- // module. Generate after descriptor bounds and initialization checks.
- pfn = [this](BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr,
- uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- return GenTexBuffCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
- new_blocks);
- };
- modified |= InstProcessEntryPointCallTree(pfn);
- }
- return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
+
+ InstProcessEntryPointCallTree(pfn);
+ // This pass always changes the memory model, so that linking will work
+ // properly.
+ return Status::SuccessWithChange;
}
Pass::Status InstBindlessCheckPass::Process() {
diff --git a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.h b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.h
index f89af025a..243cba767 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/inst_bindless_check_pass.h
@@ -28,16 +28,8 @@ namespace opt {
// external design may change as the layer evolves.
class InstBindlessCheckPass : public InstrumentPass {
public:
- InstBindlessCheckPass(uint32_t desc_set, uint32_t shader_id,
- bool desc_idx_enable, bool desc_init_enable,
- bool buffer_bounds_enable, bool texel_buffer_enable,
- bool opt_direct_reads)
- : InstrumentPass(desc_set, shader_id, kInstValidationIdBindless,
- opt_direct_reads),
- desc_idx_enabled_(desc_idx_enable),
- desc_init_enabled_(desc_init_enable),
- buffer_bounds_enabled_(buffer_bounds_enable),
- texel_buffer_enabled_(texel_buffer_enable) {}
+ InstBindlessCheckPass(uint32_t shader_id)
+ : InstrumentPass(0, shader_id, true, true) {}
~InstBindlessCheckPass() override = default;
@@ -47,82 +39,16 @@ class InstBindlessCheckPass : public InstrumentPass {
const char* name() const override { return "inst-bindless-check-pass"; }
private:
- // These functions do bindless checking instrumentation on a single
- // instruction which references through a descriptor (ie references into an
- // image or buffer). Refer to Vulkan API for further information on
- // descriptors. GenDescIdxCheckCode checks that an index into a descriptor
- // array (array of images or buffers) is in-bounds. GenDescInitCheckCode
- // checks that the referenced descriptor has been initialized, if the
- // SPV_EXT_descriptor_indexing extension is enabled, and initialized large
- // enough to handle the reference, if RobustBufferAccess is disabled.
- // GenDescInitCheckCode checks for uniform and storage buffer overrun.
- // GenTexBuffCheckCode checks for texel buffer overrun and should be
- // run after GenDescInitCheckCode to first make sure that the descriptor
- // is initialized because it uses OpImageQuerySize on the descriptor.
- //
- // The functions are designed to be passed to
- // InstrumentPass::InstProcessEntryPointCallTree(), which applies the
- // function to each instruction in a module and replaces the instruction
- // if warranted.
- //
- // If |ref_inst_itr| is a bindless reference, return in |new_blocks| the
- // result of instrumenting it with validation code within its block at
- // |ref_block_itr|. The validation code first executes a check for the
- // specific condition called for. If the check passes, it executes
- // the remainder of the reference, otherwise writes a record to the debug
- // output buffer stream including |function_idx, instruction_idx, stage_idx|
- // and replaces the reference with the null value of the original type. The
- // block at |ref_block_itr| can just be replaced with the blocks in
- // |new_blocks|, which will contain at least two blocks. The last block will
- // comprise all instructions following |ref_inst_itr|,
- // preceded by a phi instruction.
- //
- // These instrumentation functions utilize GenDebugDirectRead() to read data
- // from the debug input buffer, specifically the lengths of variable length
- // descriptor arrays, and the initialization status of each descriptor.
- // The format of the debug input buffer is documented in instrument.hpp.
- //
- // These instrumentation functions utilize GenDebugStreamWrite() to write its
- // error records. The validation-specific part of the error record will
- // have the format:
- //
- // Validation Error Code (=kInstErrorBindlessBounds)
- // Descriptor Index
- // Descriptor Array Size
- //
- // The Descriptor Index is the index which has been determined to be
- // out-of-bounds.
- //
- // The Descriptor Array Size is the size of the descriptor array which was
- // indexed.
- void GenDescIdxCheckCode(
- BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
-
- void GenDescInitCheckCode(
- BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
-
- void GenTexBuffCheckCode(
- BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
- std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
-
- void SetupInputBufferIds();
- uint32_t GenDebugReadLengthFunctionId();
-
- // Generate instructions into |builder| to read length of runtime descriptor
- // array |var_id| from debug input buffer and return id of value.
- uint32_t GenDebugReadLength(uint32_t var_id, InstructionBuilder* builder);
-
- uint32_t GenDebugReadInitFunctionId();
- // Generate instructions into |builder| to read initialization status of
- // descriptor array |image_id| at |index_id| from debug input buffer and
- // return id of value.
- uint32_t GenDebugReadInit(uint32_t image_id, uint32_t index_id,
- InstructionBuilder* builder);
+ void GenDescCheckCode(BasicBlock::iterator ref_inst_itr,
+ UptrVectorIterator<BasicBlock> ref_block_itr,
+ uint32_t stage_idx,
+ std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
+
+ uint32_t GenDescCheckFunctionId();
+
+ uint32_t GenDescCheckCall(uint32_t inst_idx, uint32_t stage_idx,
+ uint32_t var_id, uint32_t index_id,
+ uint32_t byte_offset, InstructionBuilder* builder);
// Analysis data for descriptor reference components, generated by
// AnalyzeDescriptorReference. It is necessary and sufficient for further
@@ -179,8 +105,7 @@ class InstBindlessCheckPass : public InstrumentPass {
// writes debug error output utilizing |ref|, |error_id|, |length_id| and
// |stage_idx|. Generate merge block for valid and invalid branches. Kill
// original reference.
- void GenCheckCode(uint32_t check_id, uint32_t error_id, uint32_t offset_id,
- uint32_t length_id, uint32_t stage_idx, RefAnalysis* ref,
+ void GenCheckCode(uint32_t check_id, RefAnalysis* ref,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
// Initialize state for instrumenting bindless checking
@@ -190,30 +115,13 @@ class InstBindlessCheckPass : public InstrumentPass {
// GenDescInitCheckCode to every instruction in module.
Pass::Status ProcessImpl();
- // Enable instrumentation of runtime array length checking
- bool desc_idx_enabled_;
-
- // Enable instrumentation of descriptor initialization checking
- bool desc_init_enabled_;
-
- // Enable instrumentation of uniform and storage buffer overrun checking
- bool buffer_bounds_enabled_;
-
- // Enable instrumentation of texel buffer overrun checking
- bool texel_buffer_enabled_;
-
// Mapping from variable to descriptor set
std::unordered_map<uint32_t, uint32_t> var2desc_set_;
// Mapping from variable to binding
std::unordered_map<uint32_t, uint32_t> var2binding_;
- uint32_t read_length_func_id_{0};
- uint32_t read_init_func_id_{0};
- uint32_t desc_set_type_id_{0};
- uint32_t desc_set_ptr_id_{0};
- uint32_t input_buffer_struct_id_{0};
- uint32_t input_buffer_ptr_id_{0};
+ uint32_t check_desc_func_id_{0};
};
} // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
index 495470652..e6c550878 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.cpp
@@ -19,24 +19,6 @@
namespace spvtools {
namespace opt {
-bool InstBuffAddrCheckPass::InstrumentFunction(Function* func,
- uint32_t stage_idx,
- InstProcessFunction& pfn) {
- // The bindless instrumentation pass adds functions that use
- // BufferDeviceAddress They should not be instrumented by this pass.
- Instruction* func_name_inst =
- context()->GetNames(func->DefInst().result_id()).begin()->second;
- if (func_name_inst) {
- static const std::string kPrefix{"inst_bindless_"};
- std::string func_name = func_name_inst->GetOperand(1).AsString();
- if (func_name.size() >= kPrefix.size() &&
- func_name.compare(0, kPrefix.size(), kPrefix) == 0) {
- return false;
- }
- }
- return InstrumentPass::InstrumentFunction(func, stage_idx, pfn);
-}
-
uint32_t InstBuffAddrCheckPass::CloneOriginalReference(
Instruction* ref_inst, InstructionBuilder* builder) {
// Clone original ref with new result id (if load)
@@ -76,8 +58,7 @@ bool InstBuffAddrCheckPass::IsPhysicalBuffAddrReference(Instruction* ref_inst) {
// TODO(greg-lunarg): Refactor with InstBindlessCheckPass::GenCheckCode() ??
void InstBuffAddrCheckPass::GenCheckCode(
- uint32_t check_id, uint32_t error_id, uint32_t ref_uptr_id,
- uint32_t stage_idx, Instruction* ref_inst,
+ uint32_t check_id, Instruction* ref_inst,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
BasicBlock* back_blk_ptr = &*new_blocks->back();
InstructionBuilder builder(
@@ -104,18 +85,6 @@ void InstBuffAddrCheckPass::GenCheckCode(
// Gen invalid block
new_blk_ptr.reset(new BasicBlock(std::move(invalid_label)));
builder.SetInsertPoint(&*new_blk_ptr);
- // Convert uptr from uint64 to 2 uint32
- Instruction* lo_uptr_inst =
- builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, ref_uptr_id);
- Instruction* rshift_uptr_inst =
- builder.AddBinaryOp(GetUint64Id(), spv::Op::OpShiftRightLogical,
- ref_uptr_id, builder.GetUintConstantId(32));
- Instruction* hi_uptr_inst = builder.AddUnaryOp(
- GetUintId(), spv::Op::OpUConvert, rshift_uptr_inst->result_id());
- GenDebugStreamWrite(
- uid2offset_[ref_inst->unique_id()], stage_idx,
- {error_id, lo_uptr_inst->result_id(), hi_uptr_inst->result_id()},
- &builder);
// Gen zero for invalid load. If pointer type, need to convert uint64
// zero to pointer; cannot create ConstantNull of pointer type.
uint32_t null_id = 0;
@@ -150,48 +119,13 @@ void InstBuffAddrCheckPass::GenCheckCode(
context()->KillInst(ref_inst);
}
-uint32_t InstBuffAddrCheckPass::GetTypeAlignment(uint32_t type_id) {
- Instruction* type_inst = get_def_use_mgr()->GetDef(type_id);
- switch (type_inst->opcode()) {
- case spv::Op::OpTypeFloat:
- case spv::Op::OpTypeInt:
- case spv::Op::OpTypeVector:
- return GetTypeLength(type_id);
- case spv::Op::OpTypeMatrix:
- return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
- case spv::Op::OpTypeArray:
- case spv::Op::OpTypeRuntimeArray:
- return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
- case spv::Op::OpTypeStruct: {
- uint32_t max = 0;
- type_inst->ForEachInId([&max, this](const uint32_t* iid) {
- uint32_t alignment = GetTypeAlignment(*iid);
- max = (alignment > max) ? alignment : max;
- });
- return max;
- }
- case spv::Op::OpTypePointer:
- assert(spv::StorageClass(type_inst->GetSingleWordInOperand(0)) ==
- spv::StorageClass::PhysicalStorageBufferEXT &&
- "unexpected pointer type");
- return 8u;
- default:
- assert(false && "unexpected type");
- return 0;
- }
-}
-
uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) {
Instruction* type_inst = get_def_use_mgr()->GetDef(type_id);
switch (type_inst->opcode()) {
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeInt:
return type_inst->GetSingleWordInOperand(0) / 8u;
- case spv::Op::OpTypeVector: {
- uint32_t raw_cnt = type_inst->GetSingleWordInOperand(1);
- uint32_t adj_cnt = (raw_cnt == 3u) ? 4u : raw_cnt;
- return adj_cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0));
- }
+ case spv::Op::OpTypeVector:
case spv::Op::OpTypeMatrix:
return type_inst->GetSingleWordInOperand(1) *
GetTypeLength(type_inst->GetSingleWordInOperand(0));
@@ -207,18 +141,19 @@ uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) {
return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0));
}
case spv::Op::OpTypeStruct: {
- uint32_t len = 0;
- type_inst->ForEachInId([&len, this](const uint32_t* iid) {
- // Align struct length
- uint32_t alignment = GetTypeAlignment(*iid);
- uint32_t mod = len % alignment;
- uint32_t diff = (mod != 0) ? alignment - mod : 0;
- len += diff;
- // Increment struct length by component length
- uint32_t comp_len = GetTypeLength(*iid);
- len += comp_len;
+ // Figure out the location of the last byte of the last member of the
+ // structure.
+ uint32_t last_offset = 0, last_len = 0;
+
+ get_decoration_mgr()->ForEachDecoration(
+ type_id, uint32_t(spv::Decoration::Offset),
+ [&last_offset](const Instruction& deco_inst) {
+ last_offset = deco_inst.GetSingleWordInOperand(3);
+ });
+ type_inst->ForEachInId([&last_len, this](const uint32_t* iid) {
+ last_len = GetTypeLength(*iid);
});
- return len;
+ return last_offset + last_len;
}
case spv::Op::OpTypeRuntimeArray:
default:
@@ -238,201 +173,86 @@ void InstBuffAddrCheckPass::AddParam(uint32_t type_id,
(*input_func)->AddParameter(std::move(param_inst));
}
+// This is a stub function for use with Import linkage
+// clang-format off
+// GLSL:
+//bool inst_bindless_search_and_test(const uint shader_id, const uint inst_num, const uvec4 stage_info,
+// const uint64 ref_ptr, const uint length) {
+//}
+// clang-format on
uint32_t InstBuffAddrCheckPass::GetSearchAndTestFuncId() {
- if (search_test_func_id_ == 0) {
- // Generate function "bool search_and_test(uint64_t ref_ptr, uint32_t len)"
- // which searches input buffer for buffer which most likely contains the
- // pointer value |ref_ptr| and verifies that the entire reference of
- // length |len| bytes is contained in the buffer.
- search_test_func_id_ = TakeNextId();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- std::vector<const analysis::Type*> param_types = {
- type_mgr->GetType(GetUint64Id()), type_mgr->GetType(GetUintId())};
- analysis::Function func_ty(type_mgr->GetType(GetBoolId()), param_types);
- analysis::Type* reg_func_ty = type_mgr->GetRegisteredType(&func_ty);
- std::unique_ptr<Instruction> func_inst(
- new Instruction(get_module()->context(), spv::Op::OpFunction,
- GetBoolId(), search_test_func_id_,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::FunctionControlMask::MaskNone)}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {type_mgr->GetTypeInstruction(reg_func_ty)}}}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_inst);
- std::unique_ptr<Function> input_func =
- MakeUnique<Function>(std::move(func_inst));
- std::vector<uint32_t> param_vec;
- // Add ref_ptr and length parameters
- AddParam(GetUint64Id(), &param_vec, &input_func);
- AddParam(GetUintId(), &param_vec, &input_func);
- // Empty first block.
- uint32_t first_blk_id = TakeNextId();
- std::unique_ptr<Instruction> first_blk_label(NewLabel(first_blk_id));
- std::unique_ptr<BasicBlock> first_blk_ptr =
- MakeUnique<BasicBlock>(std::move(first_blk_label));
- InstructionBuilder builder(
- context(), &*first_blk_ptr,
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- uint32_t hdr_blk_id = TakeNextId();
- // Branch to search loop header
- std::unique_ptr<Instruction> hdr_blk_label(NewLabel(hdr_blk_id));
- (void)builder.AddBranch(hdr_blk_id);
- input_func->AddBasicBlock(std::move(first_blk_ptr));
- // Linear search loop header block
- // TODO(greg-lunarg): Implement binary search
- std::unique_ptr<BasicBlock> hdr_blk_ptr =
- MakeUnique<BasicBlock>(std::move(hdr_blk_label));
- builder.SetInsertPoint(&*hdr_blk_ptr);
- // Phi for search index. Starts with 1.
- uint32_t cont_blk_id = TakeNextId();
- std::unique_ptr<Instruction> cont_blk_label(NewLabel(cont_blk_id));
- // Deal with def-use cycle caused by search loop index computation.
- // Create Add and Phi instructions first, then do Def analysis on Add.
- // Add Phi and Add instructions and do Use analysis later.
- uint32_t idx_phi_id = TakeNextId();
- uint32_t idx_inc_id = TakeNextId();
- std::unique_ptr<Instruction> idx_inc_inst(new Instruction(
- context(), spv::Op::OpIAdd, GetUintId(), idx_inc_id,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {idx_phi_id}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {builder.GetUintConstantId(1u)}}}));
- std::unique_ptr<Instruction> idx_phi_inst(new Instruction(
- context(), spv::Op::OpPhi, GetUintId(), idx_phi_id,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {builder.GetUintConstantId(1u)}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {first_blk_id}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {idx_inc_id}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {cont_blk_id}}}));
- get_def_use_mgr()->AnalyzeInstDef(&*idx_inc_inst);
- // Add (previously created) search index phi
- (void)builder.AddInstruction(std::move(idx_phi_inst));
- // LoopMerge
- uint32_t bound_test_blk_id = TakeNextId();
- std::unique_ptr<Instruction> bound_test_blk_label(
- NewLabel(bound_test_blk_id));
- (void)builder.AddLoopMerge(bound_test_blk_id, cont_blk_id,
- uint32_t(spv::LoopControlMask::MaskNone));
- // Branch to continue/work block
- (void)builder.AddBranch(cont_blk_id);
- input_func->AddBasicBlock(std::move(hdr_blk_ptr));
- // Continue/Work Block. Read next buffer pointer and break if greater
- // than ref_ptr arg.
- std::unique_ptr<BasicBlock> cont_blk_ptr =
- MakeUnique<BasicBlock>(std::move(cont_blk_label));
- builder.SetInsertPoint(&*cont_blk_ptr);
- // Add (previously created) search index increment now.
- (void)builder.AddInstruction(std::move(idx_inc_inst));
- // Load next buffer address from debug input buffer
- uint32_t ibuf_id = GetInputBufferId();
- uint32_t ibuf_ptr_id = GetInputBufferPtrId();
- Instruction* uptr_ac_inst = builder.AddTernaryOp(
- ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id,
- builder.GetUintConstantId(kDebugInputDataOffset), idx_inc_id);
- uint32_t ibuf_type_id = GetInputBufferTypeId();
- Instruction* uptr_load_inst = builder.AddUnaryOp(
- ibuf_type_id, spv::Op::OpLoad, uptr_ac_inst->result_id());
- // If loaded address greater than ref_ptr arg, break, else branch back to
- // loop header
- Instruction* uptr_test_inst =
- builder.AddBinaryOp(GetBoolId(), spv::Op::OpUGreaterThan,
- uptr_load_inst->result_id(), param_vec[0]);
- (void)builder.AddConditionalBranch(
- uptr_test_inst->result_id(), bound_test_blk_id, hdr_blk_id, kInvalidId,
- uint32_t(spv::SelectionControlMask::MaskNone));
- input_func->AddBasicBlock(std::move(cont_blk_ptr));
- // Bounds test block. Read length of selected buffer and test that
- // all len arg bytes are in buffer.
- std::unique_ptr<BasicBlock> bound_test_blk_ptr =
- MakeUnique<BasicBlock>(std::move(bound_test_blk_label));
- builder.SetInsertPoint(&*bound_test_blk_ptr);
- // Decrement index to point to previous/candidate buffer address
- Instruction* cand_idx_inst =
- builder.AddBinaryOp(GetUintId(), spv::Op::OpISub, idx_inc_id,
- builder.GetUintConstantId(1u));
- // Load candidate buffer address
- Instruction* cand_ac_inst =
- builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id,
- builder.GetUintConstantId(kDebugInputDataOffset),
- cand_idx_inst->result_id());
- Instruction* cand_load_inst = builder.AddUnaryOp(
- ibuf_type_id, spv::Op::OpLoad, cand_ac_inst->result_id());
- // Compute offset of ref_ptr from candidate buffer address
- Instruction* offset_inst =
- builder.AddBinaryOp(ibuf_type_id, spv::Op::OpISub, param_vec[0],
- cand_load_inst->result_id());
- // Convert ref length to uint64
- Instruction* ref_len_64_inst =
- builder.AddUnaryOp(ibuf_type_id, spv::Op::OpUConvert, param_vec[1]);
- // Add ref length to ref offset to compute end of reference
- Instruction* ref_end_inst = builder.AddBinaryOp(
- ibuf_type_id, spv::Op::OpIAdd, offset_inst->result_id(),
- ref_len_64_inst->result_id());
- // Load starting index of lengths in input buffer and convert to uint32
- Instruction* len_start_ac_inst =
- builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id,
- builder.GetUintConstantId(kDebugInputDataOffset),
- builder.GetUintConstantId(0u));
- Instruction* len_start_load_inst = builder.AddUnaryOp(
- ibuf_type_id, spv::Op::OpLoad, len_start_ac_inst->result_id());
- Instruction* len_start_32_inst = builder.AddUnaryOp(
- GetUintId(), spv::Op::OpUConvert, len_start_load_inst->result_id());
- // Decrement search index to get candidate buffer length index
- Instruction* cand_len_idx_inst = builder.AddBinaryOp(
- GetUintId(), spv::Op::OpISub, cand_idx_inst->result_id(),
- builder.GetUintConstantId(1u));
- // Add candidate length index to start index
- Instruction* len_idx_inst = builder.AddBinaryOp(
- GetUintId(), spv::Op::OpIAdd, cand_len_idx_inst->result_id(),
- len_start_32_inst->result_id());
- // Load candidate buffer length
- Instruction* len_ac_inst =
- builder.AddTernaryOp(ibuf_ptr_id, spv::Op::OpAccessChain, ibuf_id,
- builder.GetUintConstantId(kDebugInputDataOffset),
- len_idx_inst->result_id());
- Instruction* len_load_inst = builder.AddUnaryOp(
- ibuf_type_id, spv::Op::OpLoad, len_ac_inst->result_id());
- // Test if reference end within candidate buffer length
- Instruction* len_test_inst = builder.AddBinaryOp(
- GetBoolId(), spv::Op::OpULessThanEqual, ref_end_inst->result_id(),
- len_load_inst->result_id());
- // Return test result
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue,
- len_test_inst->result_id());
- // Close block
- input_func->AddBasicBlock(std::move(bound_test_blk_ptr));
- // Close function and add function to module
- std::unique_ptr<Instruction> func_end_inst(new Instruction(
- get_module()->context(), spv::Op::OpFunctionEnd, 0, 0, {}));
- get_def_use_mgr()->AnalyzeInstDefUse(&*func_end_inst);
- input_func->SetFunctionEnd(std::move(func_end_inst));
- context()->AddFunction(std::move(input_func));
- context()->AddDebug2Inst(
- NewGlobalName(search_test_func_id_, "search_and_test"));
+ enum {
+ kShaderId = 0,
+ kInstructionIndex = 1,
+ kStageInfo = 2,
+ kRefPtr = 3,
+ kLength = 4,
+ kNumArgs
+ };
+ if (search_test_func_id_ != 0) {
+ return search_test_func_id_;
}
+ // Generate function "bool search_and_test(uint64_t ref_ptr, uint32_t len)"
+ // which searches input buffer for buffer which most likely contains the
+ // pointer value |ref_ptr| and verifies that the entire reference of
+ // length |len| bytes is contained in the buffer.
+ analysis::TypeManager* type_mgr = context()->get_type_mgr();
+ const analysis::Integer* uint_type = GetInteger(32, false);
+ const analysis::Vector v4uint(uint_type, 4);
+ const analysis::Type* v4uint_type = type_mgr->GetRegisteredType(&v4uint);
+
+ std::vector<const analysis::Type*> param_types = {
+ uint_type, uint_type, v4uint_type, type_mgr->GetType(GetUint64Id()),
+ uint_type};
+
+ const std::string func_name{"inst_buff_addr_search_and_test"};
+ const uint32_t func_id = TakeNextId();
+ std::unique_ptr<Function> func =
+ StartFunction(func_id, type_mgr->GetBoolType(), param_types);
+ func->SetFunctionEnd(EndFunction());
+ context()->AddFunctionDeclaration(std::move(func));
+ context()->AddDebug2Inst(NewName(func_id, func_name));
+
+ std::vector<Operand> operands{
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {func_id}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+ {uint32_t(spv::Decoration::LinkageAttributes)}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_STRING,
+ utils::MakeVector(func_name.c_str())},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_LINKAGE_TYPE,
+ {uint32_t(spv::LinkageType::Import)}},
+ };
+ get_decoration_mgr()->AddDecoration(spv::Op::OpDecorate, operands);
+
+ search_test_func_id_ = func_id;
return search_test_func_id_;
}
uint32_t InstBuffAddrCheckPass::GenSearchAndTest(Instruction* ref_inst,
InstructionBuilder* builder,
- uint32_t* ref_uptr_id) {
+ uint32_t* ref_uptr_id,
+ uint32_t stage_idx) {
// Enable Int64 if necessary
- context()->AddCapability(spv::Capability::Int64);
// Convert reference pointer to uint64
- uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0);
+ const uint32_t ref_ptr_id = ref_inst->GetSingleWordInOperand(0);
Instruction* ref_uptr_inst =
builder->AddUnaryOp(GetUint64Id(), spv::Op::OpConvertPtrToU, ref_ptr_id);
*ref_uptr_id = ref_uptr_inst->result_id();
// Compute reference length in bytes
analysis::DefUseManager* du_mgr = get_def_use_mgr();
Instruction* ref_ptr_inst = du_mgr->GetDef(ref_ptr_id);
- uint32_t ref_ptr_ty_id = ref_ptr_inst->type_id();
+ const uint32_t ref_ptr_ty_id = ref_ptr_inst->type_id();
Instruction* ref_ptr_ty_inst = du_mgr->GetDef(ref_ptr_ty_id);
- uint32_t ref_len = GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1));
- uint32_t ref_len_id = builder->GetUintConstantId(ref_len);
+ const uint32_t ref_len =
+ GetTypeLength(ref_ptr_ty_inst->GetSingleWordInOperand(1));
// Gen call to search and test function
- Instruction* call_inst = builder->AddFunctionCall(
- GetBoolId(), GetSearchAndTestFuncId(), {*ref_uptr_id, ref_len_id});
- uint32_t retval = call_inst->result_id();
- return retval;
+ const uint32_t func_id = GetSearchAndTestFuncId();
+ const std::vector<uint32_t> args = {
+ builder->GetUintConstantId(shader_id_),
+ builder->GetUintConstantId(ref_inst->unique_id()),
+ GenStageInfo(stage_idx, builder), *ref_uptr_id,
+ builder->GetUintConstantId(ref_len)};
+ return GenReadFunctionCall(GetBoolId(), func_id, args, builder);
}
void InstBuffAddrCheckPass::GenBuffAddrCheckCode(
@@ -450,16 +270,16 @@ void InstBuffAddrCheckPass::GenBuffAddrCheckCode(
context(), &*new_blk_ptr,
IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
new_blocks->push_back(std::move(new_blk_ptr));
- uint32_t error_id = builder.GetUintConstantId(kInstErrorBuffAddrUnallocRef);
// Generate code to do search and test if all bytes of reference
// are within a listed buffer. Return reference pointer converted to uint64.
uint32_t ref_uptr_id;
- uint32_t valid_id = GenSearchAndTest(ref_inst, &builder, &ref_uptr_id);
+ uint32_t valid_id =
+ GenSearchAndTest(ref_inst, &builder, &ref_uptr_id, stage_idx);
// Generate test of search results with true branch
// being full reference and false branch being debug output and zero
// for the referenced value.
- GenCheckCode(valid_id, error_id, ref_uptr_id, stage_idx, ref_inst,
- new_blocks);
+ GenCheckCode(valid_id, ref_inst, new_blocks);
+
// Move original block's remaining code into remainder/merge block and add
// to new blocks
BasicBlock* back_blk_ptr = &*new_blocks->back();
@@ -474,6 +294,20 @@ void InstBuffAddrCheckPass::InitInstBuffAddrCheck() {
}
Pass::Status InstBuffAddrCheckPass::ProcessImpl() {
+ // The memory model and linkage must always be updated for spirv-link to work
+ // correctly.
+ AddStorageBufferExt();
+ if (!get_feature_mgr()->HasExtension(kSPV_KHR_physical_storage_buffer)) {
+ context()->AddExtension("SPV_KHR_physical_storage_buffer");
+ }
+
+ context()->AddCapability(spv::Capability::PhysicalStorageBufferAddresses);
+ Instruction* memory_model = get_module()->GetMemoryModel();
+ memory_model->SetInOperand(
+ 0u, {uint32_t(spv::AddressingModel::PhysicalStorageBuffer64)});
+
+ context()->AddCapability(spv::Capability::Int64);
+ context()->AddCapability(spv::Capability::Linkage);
// Perform bindless bounds check on each entry point function in module
InstProcessFunction pfn =
[this](BasicBlock::iterator ref_inst_itr,
@@ -482,14 +316,13 @@ Pass::Status InstBuffAddrCheckPass::ProcessImpl() {
return GenBuffAddrCheckCode(ref_inst_itr, ref_block_itr, stage_idx,
new_blocks);
};
- bool modified = InstProcessEntryPointCallTree(pfn);
- return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
+ InstProcessEntryPointCallTree(pfn);
+ // This pass always changes the memory model, so that linking will work
+ // properly.
+ return Status::SuccessWithChange;
}
Pass::Status InstBuffAddrCheckPass::Process() {
- if (!get_feature_mgr()->HasCapability(
- spv::Capability::PhysicalStorageBufferAddressesEXT))
- return Status::SuccessWithoutChange;
InitInstBuffAddrCheck();
return ProcessImpl();
}
diff --git a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.h b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.h
index 2ec212bf8..f07f98a0f 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/inst_buff_addr_check_pass.h
@@ -29,10 +29,10 @@ namespace opt {
class InstBuffAddrCheckPass : public InstrumentPass {
public:
// For test harness only
- InstBuffAddrCheckPass() : InstrumentPass(7, 23, kInstValidationIdBuffAddr) {}
+ InstBuffAddrCheckPass() : InstrumentPass(0, 23, false, true) {}
// For all other interfaces
- InstBuffAddrCheckPass(uint32_t desc_set, uint32_t shader_id)
- : InstrumentPass(desc_set, shader_id, kInstValidationIdBuffAddr) {}
+ InstBuffAddrCheckPass(uint32_t shader_id)
+ : InstrumentPass(0, shader_id, false, true) {}
~InstBuffAddrCheckPass() override = default;
@@ -41,14 +41,7 @@ class InstBuffAddrCheckPass : public InstrumentPass {
const char* name() const override { return "inst-buff-addr-check-pass"; }
- bool InstrumentFunction(Function* func, uint32_t stage_idx,
- InstProcessFunction& pfn) override;
-
private:
- // Return byte alignment of type |type_id|. Must be int, float, vector,
- // matrix, struct, array or physical pointer. Uses std430 alignment.
- uint32_t GetTypeAlignment(uint32_t type_id);
-
// Return byte length of type |type_id|. Must be int, float, vector, matrix,
// struct, array or physical pointer. Uses std430 alignment and sizes.
uint32_t GetTypeLength(uint32_t type_id);
@@ -65,7 +58,7 @@ class InstBuffAddrCheckPass : public InstrumentPass {
// are within the buffer. Returns id of boolean value which is true if
// search and test is successful, false otherwise.
uint32_t GenSearchAndTest(Instruction* ref_inst, InstructionBuilder* builder,
- uint32_t* ref_uptr_id);
+ uint32_t* ref_uptr_id, uint32_t stage_idx);
// This function does checking instrumentation on a single
// instruction which references through a physical storage buffer address.
@@ -118,8 +111,7 @@ class InstBuffAddrCheckPass : public InstrumentPass {
// writes debug error output utilizing |ref_inst|, |error_id| and
// |stage_idx|. Generate merge block for valid and invalid reference blocks.
// Kill original reference.
- void GenCheckCode(uint32_t check_id, uint32_t error_id, uint32_t length_id,
- uint32_t stage_idx, Instruction* ref_inst,
+ void GenCheckCode(uint32_t check_id, Instruction* ref_inst,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
// Initialize state for instrumenting physical buffer address checking
diff --git a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
index 4f9727781..abd25e939 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.cpp
@@ -16,6 +16,7 @@
#include "inst_debug_printf_pass.h"
+#include "source/spirv_constant.h"
#include "source/util/string_utils.h"
#include "spirv/unified1/NonSemanticDebugPrintf.h"
@@ -137,7 +138,7 @@ void InstDebugPrintfPass::GenOutputValues(Instruction* val_inst,
}
void InstDebugPrintfPass::GenOutputCode(
- Instruction* printf_inst, uint32_t stage_idx,
+ Instruction* printf_inst,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
BasicBlock* back_blk_ptr = &*new_blocks->back();
InstructionBuilder builder(
@@ -165,14 +166,16 @@ void InstDebugPrintfPass::GenOutputCode(
GenOutputValues(opnd_inst, &val_ids, &builder);
}
});
- GenDebugStreamWrite(uid2offset_[printf_inst->unique_id()], stage_idx, val_ids,
- &builder);
+ GenDebugStreamWrite(
+ builder.GetUintConstantId(shader_id_),
+ builder.GetUintConstantId(uid2offset_[printf_inst->unique_id()]), val_ids,
+ &builder);
context()->KillInst(printf_inst);
}
void InstDebugPrintfPass::GenDebugPrintfCode(
BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
+ UptrVectorIterator<BasicBlock> ref_block_itr,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
// If not DebugPrintf OpExtInst, return.
Instruction* printf_inst = &*ref_inst_itr;
@@ -188,7 +191,7 @@ void InstDebugPrintfPass::GenDebugPrintfCode(
MovePreludeCode(ref_inst_itr, ref_block_itr, &new_blk_ptr);
new_blocks->push_back(std::move(new_blk_ptr));
// Generate instructions to output printf args to printf buffer
- GenOutputCode(printf_inst, stage_idx, new_blocks);
+ GenOutputCode(printf_inst, new_blocks);
// Caller expects at least two blocks with last block containing remaining
// code, so end block after instrumentation, create remainder block, and
// branch to it
@@ -208,19 +211,243 @@ void InstDebugPrintfPass::GenDebugPrintfCode(
new_blocks->push_back(std::move(new_blk_ptr));
}
+// Return id for output buffer
+uint32_t InstDebugPrintfPass::GetOutputBufferId() {
+ if (output_buffer_id_ == 0) {
+ // If not created yet, create one
+ analysis::DecorationManager* deco_mgr = get_decoration_mgr();
+ analysis::TypeManager* type_mgr = context()->get_type_mgr();
+ analysis::RuntimeArray* reg_uint_rarr_ty = GetUintRuntimeArrayType(32);
+ analysis::Integer* reg_uint_ty = GetInteger(32, false);
+ analysis::Type* reg_buf_ty =
+ GetStruct({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty});
+ uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty);
+ // By the Vulkan spec, a pre-existing struct containing a RuntimeArray
+ // must be a block, and will therefore be decorated with Block. Therefore
+ // the undecorated type returned here will not be pre-existing and can
+ // safely be decorated. Since this type is now decorated, it is out of
+ // sync with the TypeManager and therefore the TypeManager must be
+ // invalidated after this pass.
+ assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 &&
+ "used struct type returned");
+ deco_mgr->AddDecoration(obufTyId, uint32_t(spv::Decoration::Block));
+ deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputFlagsOffset,
+ uint32_t(spv::Decoration::Offset), 0);
+ deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset,
+ uint32_t(spv::Decoration::Offset), 4);
+ deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset,
+ uint32_t(spv::Decoration::Offset), 8);
+ uint32_t obufTyPtrId_ =
+ type_mgr->FindPointerToType(obufTyId, spv::StorageClass::StorageBuffer);
+ output_buffer_id_ = TakeNextId();
+ std::unique_ptr<Instruction> newVarOp(new Instruction(
+ context(), spv::Op::OpVariable, obufTyPtrId_, output_buffer_id_,
+ {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
+ {uint32_t(spv::StorageClass::StorageBuffer)}}}));
+ context()->AddGlobalValue(std::move(newVarOp));
+ context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer"));
+ context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "flags"));
+ context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "written_count"));
+ context()->AddDebug2Inst(NewMemberName(obufTyId, 2, "data"));
+ context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer"));
+ deco_mgr->AddDecorationVal(
+ output_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_);
+ deco_mgr->AddDecorationVal(output_buffer_id_,
+ uint32_t(spv::Decoration::Binding),
+ GetOutputBufferBinding());
+ AddStorageBufferExt();
+ if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
+ // Add the new buffer to all entry points.
+ for (auto& entry : get_module()->entry_points()) {
+ entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}});
+ context()->AnalyzeUses(&entry);
+ }
+ }
+ }
+ return output_buffer_id_;
+}
+
+uint32_t InstDebugPrintfPass::GetOutputBufferPtrId() {
+ if (output_buffer_ptr_id_ == 0) {
+ output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType(
+ GetUintId(), spv::StorageClass::StorageBuffer);
+ }
+ return output_buffer_ptr_id_;
+}
+
+uint32_t InstDebugPrintfPass::GetOutputBufferBinding() {
+ return kDebugOutputPrintfStream;
+}
+
+void InstDebugPrintfPass::GenDebugOutputFieldCode(uint32_t base_offset_id,
+ uint32_t field_offset,
+ uint32_t field_value_id,
+ InstructionBuilder* builder) {
+ // Cast value to 32-bit unsigned if necessary
+ uint32_t val_id = GenUintCastCode(field_value_id, builder);
+ // Store value
+ Instruction* data_idx_inst = builder->AddIAdd(
+ GetUintId(), base_offset_id, builder->GetUintConstantId(field_offset));
+ uint32_t buf_id = GetOutputBufferId();
+ uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
+ Instruction* achain_inst = builder->AddAccessChain(
+ buf_uint_ptr_id, buf_id,
+ {builder->GetUintConstantId(kDebugOutputDataOffset),
+ data_idx_inst->result_id()});
+ (void)builder->AddStore(achain_inst->result_id(), val_id);
+}
+
+uint32_t InstDebugPrintfPass::GetStreamWriteFunctionId(uint32_t param_cnt) {
+ enum {
+ kShaderId = 0,
+ kInstructionIndex = 1,
+ kFirstParam = 2,
+ };
+ // Total param count is common params plus validation-specific
+ // params
+ if (param2output_func_id_[param_cnt] == 0) {
+ // Create function
+ param2output_func_id_[param_cnt] = TakeNextId();
+ analysis::TypeManager* type_mgr = context()->get_type_mgr();
+
+ const analysis::Type* uint_type = GetInteger(32, false);
+
+ std::vector<const analysis::Type*> param_types(kFirstParam + param_cnt,
+ uint_type);
+ std::unique_ptr<Function> output_func = StartFunction(
+ param2output_func_id_[param_cnt], type_mgr->GetVoidType(), param_types);
+
+ std::vector<uint32_t> param_ids = AddParameters(*output_func, param_types);
+
+ // Create first block
+ auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
+
+ InstructionBuilder builder(
+ context(), &*new_blk_ptr,
+ IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
+ // Gen test if debug output buffer size will not be exceeded.
+ const uint32_t first_param_offset = kInstCommonOutInstructionIdx + 1;
+ const uint32_t obuf_record_sz = first_param_offset + param_cnt;
+ const uint32_t buf_id = GetOutputBufferId();
+ const uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
+ Instruction* obuf_curr_sz_ac_inst = builder.AddAccessChain(
+ buf_uint_ptr_id, buf_id,
+ {builder.GetUintConstantId(kDebugOutputSizeOffset)});
+ // Fetch the current debug buffer written size atomically, adding the
+ // size of the record to be written.
+ uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz);
+ uint32_t mask_none_id =
+ builder.GetUintConstantId(uint32_t(spv::MemoryAccessMask::MaskNone));
+ uint32_t scope_invok_id =
+ builder.GetUintConstantId(uint32_t(spv::Scope::Invocation));
+ Instruction* obuf_curr_sz_inst = builder.AddQuadOp(
+ GetUintId(), spv::Op::OpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(),
+ scope_invok_id, mask_none_id, obuf_record_sz_id);
+ uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id();
+ // Compute new written size
+ Instruction* obuf_new_sz_inst =
+ builder.AddIAdd(GetUintId(), obuf_curr_sz_id,
+ builder.GetUintConstantId(obuf_record_sz));
+ // Fetch the data bound
+ Instruction* obuf_bnd_inst =
+ builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength,
+ GetOutputBufferId(), kDebugOutputDataOffset);
+ // Test that new written size is less than or equal to debug output
+ // data bound
+ Instruction* obuf_safe_inst = builder.AddBinaryOp(
+ GetBoolId(), spv::Op::OpULessThanEqual, obuf_new_sz_inst->result_id(),
+ obuf_bnd_inst->result_id());
+ uint32_t merge_blk_id = TakeNextId();
+ uint32_t write_blk_id = TakeNextId();
+ std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
+ std::unique_ptr<Instruction> write_label(NewLabel(write_blk_id));
+ (void)builder.AddConditionalBranch(
+ obuf_safe_inst->result_id(), write_blk_id, merge_blk_id, merge_blk_id,
+ uint32_t(spv::SelectionControlMask::MaskNone));
+ // Close safety test block and gen write block
+ output_func->AddBasicBlock(std::move(new_blk_ptr));
+ new_blk_ptr = MakeUnique<BasicBlock>(std::move(write_label));
+ builder.SetInsertPoint(&*new_blk_ptr);
+ // Generate common and stage-specific debug record members
+ GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutSize,
+ builder.GetUintConstantId(obuf_record_sz),
+ &builder);
+ // Store Shader Id
+ GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutShaderId,
+ param_ids[kShaderId], &builder);
+ // Store Instruction Idx
+ GenDebugOutputFieldCode(obuf_curr_sz_id, kInstCommonOutInstructionIdx,
+ param_ids[kInstructionIndex], &builder);
+ // Gen writes of validation specific data
+ for (uint32_t i = 0; i < param_cnt; ++i) {
+ GenDebugOutputFieldCode(obuf_curr_sz_id, first_param_offset + i,
+ param_ids[kFirstParam + i], &builder);
+ }
+ // Close write block and gen merge block
+ (void)builder.AddBranch(merge_blk_id);
+ output_func->AddBasicBlock(std::move(new_blk_ptr));
+ new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
+ builder.SetInsertPoint(&*new_blk_ptr);
+ // Close merge block and function and add function to module
+ (void)builder.AddNullaryOp(0, spv::Op::OpReturn);
+
+ output_func->AddBasicBlock(std::move(new_blk_ptr));
+ output_func->SetFunctionEnd(EndFunction());
+ context()->AddFunction(std::move(output_func));
+
+ std::string name("stream_write_");
+ name += std::to_string(param_cnt);
+
+ context()->AddDebug2Inst(
+ NewGlobalName(param2output_func_id_[param_cnt], name));
+ }
+ return param2output_func_id_[param_cnt];
+}
+
+void InstDebugPrintfPass::GenDebugStreamWrite(
+ uint32_t shader_id, uint32_t instruction_idx_id,
+ const std::vector<uint32_t>& validation_ids, InstructionBuilder* builder) {
+ // Call debug output function. Pass func_idx, instruction_idx and
+ // validation ids as args.
+ uint32_t val_id_cnt = static_cast<uint32_t>(validation_ids.size());
+ std::vector<uint32_t> args = {shader_id, instruction_idx_id};
+ (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end());
+ (void)builder->AddFunctionCall(GetVoidId(),
+ GetStreamWriteFunctionId(val_id_cnt), args);
+}
+
+std::unique_ptr<Instruction> InstDebugPrintfPass::NewGlobalName(
+ uint32_t id, const std::string& name_str) {
+ std::string prefixed_name{"inst_printf_"};
+ prefixed_name += name_str;
+ return NewName(id, prefixed_name);
+}
+
+std::unique_ptr<Instruction> InstDebugPrintfPass::NewMemberName(
+ uint32_t id, uint32_t member_index, const std::string& name_str) {
+ return MakeUnique<Instruction>(
+ context(), spv::Op::OpMemberName, 0, 0,
+ std::initializer_list<Operand>{
+ {SPV_OPERAND_TYPE_ID, {id}},
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}},
+ {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}});
+}
+
void InstDebugPrintfPass::InitializeInstDebugPrintf() {
// Initialize base class
InitializeInstrument();
+ output_buffer_id_ = 0;
+ output_buffer_ptr_id_ = 0;
}
Pass::Status InstDebugPrintfPass::ProcessImpl() {
// Perform printf instrumentation on each entry point function in module
InstProcessFunction pfn =
[this](BasicBlock::iterator ref_inst_itr,
- UptrVectorIterator<BasicBlock> ref_block_itr, uint32_t stage_idx,
+ UptrVectorIterator<BasicBlock> ref_block_itr,
+ [[maybe_unused]] uint32_t stage_idx,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
- return GenDebugPrintfCode(ref_inst_itr, ref_block_itr, stage_idx,
- new_blocks);
+ return GenDebugPrintfCode(ref_inst_itr, ref_block_itr, new_blocks);
};
(void)InstProcessEntryPointCallTree(pfn);
// Remove DebugPrintf OpExtInstImport instruction
@@ -239,15 +466,7 @@ Pass::Status InstDebugPrintfPass::ProcessImpl() {
}
}
if (!non_sem_set_seen) {
- for (auto c_itr = context()->module()->extension_begin();
- c_itr != context()->module()->extension_end(); ++c_itr) {
- const std::string ext_name = c_itr->GetInOperand(0).AsString();
- if (ext_name == "SPV_KHR_non_semantic_info") {
- context()->KillInst(&*c_itr);
- break;
- }
- }
- context()->get_feature_mgr()->RemoveExtension(kSPV_KHR_non_semantic_info);
+ context()->RemoveExtension(kSPV_KHR_non_semantic_info);
}
return Status::SuccessWithChange;
}
diff --git a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.h b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.h
index 70b0a72bd..5688d3841 100644
--- a/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/inst_debug_printf_pass.h
@@ -28,10 +28,10 @@ namespace opt {
class InstDebugPrintfPass : public InstrumentPass {
public:
// For test harness only
- InstDebugPrintfPass() : InstrumentPass(7, 23, kInstValidationIdDebugPrintf) {}
+ InstDebugPrintfPass() : InstrumentPass(7, 23, false, false) {}
// For all other interfaces
InstDebugPrintfPass(uint32_t desc_set, uint32_t shader_id)
- : InstrumentPass(desc_set, shader_id, kInstValidationIdDebugPrintf) {}
+ : InstrumentPass(desc_set, shader_id, false, false) {}
~InstDebugPrintfPass() override = default;
@@ -41,12 +41,92 @@ class InstDebugPrintfPass : public InstrumentPass {
const char* name() const override { return "inst-printf-pass"; }
private:
+ // Gen code into |builder| to write |field_value_id| into debug output
+ // buffer at |base_offset_id| + |field_offset|.
+ void GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t field_offset,
+ uint32_t field_value_id,
+ InstructionBuilder* builder);
+
+ // Generate instructions in |builder| which will atomically fetch and
+ // increment the size of the debug output buffer stream of the current
+ // validation and write a record to the end of the stream, if enough space
+ // in the buffer remains. The record will contain the index of the function
+ // and instruction within that function |func_idx, instruction_idx| which
+ // generated the record. Finally, the record will contain validation-specific
+ // data contained in |validation_ids| which will identify the validation
+ // error as well as the values involved in the error.
+ //
+ // The output buffer binding written to by the code generated by the function
+ // is determined by the validation id specified when each specific
+ // instrumentation pass is created.
+ //
+ // The output buffer is a sequence of 32-bit values with the following
+ // format (where all elements are unsigned 32-bit unless otherwise noted):
+ //
+ // Size
+ // Record0
+ // Record1
+ // Record2
+ // ...
+ //
+ // Size is the number of 32-bit values that have been written or
+ // attempted to be written to the output buffer, excluding the Size. It is
+ // initialized to 0. If the size of attempts to write the buffer exceeds
+ // the actual size of the buffer, it is possible that this field can exceed
+ // the actual size of the buffer.
+ //
+ // Each Record* is a variable-length sequence of 32-bit values with the
+ // following format defined using static const offsets in the .cpp file:
+ //
+ // Record Size
+ // Shader ID
+ // Instruction Index
+ // ...
+ // Validation Error Code
+ // Validation-specific Word 0
+ // Validation-specific Word 1
+ // Validation-specific Word 2
+ // ...
+ //
+ // Each record consists of two subsections: members common across all
+ // validation and members specific to a
+ // validation.
+ //
+ // The Record Size is the number of 32-bit words in the record, including
+ // the Record Size word.
+ //
+ // Shader ID is a value that identifies which shader has generated the
+ // validation error. It is passed when the instrumentation pass is created.
+ //
+ // The Instruction Index is the position of the instruction within the
+ // SPIR-V file which is in error.
+ //
+ // The Validation Error Code specifies the exact error which has occurred.
+ // These are enumerated with the kInstError* static consts. This allows
+ // multiple validation layers to use the same, single output buffer.
+ //
+ // The Validation-specific Words are a validation-specific number of 32-bit
+ // words which give further information on the validation error that
+ // occurred. These are documented further in each file containing the
+ // validation-specific class which derives from this base class.
+ //
+ // Because the code that is generated checks against the size of the buffer
+ // before writing, the size of the debug out buffer can be used by the
+ // validation layer to control the number of error records that are written.
+ void GenDebugStreamWrite(uint32_t shader_id, uint32_t instruction_idx_id,
+ const std::vector<uint32_t>& validation_ids,
+ InstructionBuilder* builder);
+
+ // Return id for output function. Define if it doesn't exist with
+ // |val_spec_param_cnt| validation-specific uint32 parameters.
+ uint32_t GetStreamWriteFunctionId(uint32_t val_spec_param_cnt);
+
// Generate instructions for OpDebugPrintf.
//
// If |ref_inst_itr| is an OpDebugPrintf, return in |new_blocks| the result
// of replacing it with buffer write instructions within its block at
// |ref_block_itr|. The instructions write a record to the printf
- // output buffer stream including |function_idx, instruction_idx, stage_idx|
+ // output buffer stream including |function_idx, instruction_idx|
// and removes the OpDebugPrintf. The block at |ref_block_itr| can just be
// replaced with the block in |new_blocks|. Besides the buffer writes, this
// block will comprise all instructions preceding and following
@@ -64,7 +144,6 @@ class InstDebugPrintfPass : public InstrumentPass {
// DebugPrintf.
void GenDebugPrintfCode(BasicBlock::iterator ref_inst_itr,
UptrVectorIterator<BasicBlock> ref_block_itr,
- uint32_t stage_idx,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
// Generate a sequence of uint32 instructions in |builder| (if necessary)
@@ -77,16 +156,40 @@ class InstDebugPrintfPass : public InstrumentPass {
// Generate instructions to write a record containing the operands of
// |printf_inst| arguments to printf buffer, adding new code to the end of
// the last block in |new_blocks|. Kill OpDebugPrintf instruction.
- void GenOutputCode(Instruction* printf_inst, uint32_t stage_idx,
+ void GenOutputCode(Instruction* printf_inst,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks);
+ // Set the name for a function or global variable, names will be
+ // prefixed to identify which instrumentation pass generated them.
+ std::unique_ptr<Instruction> NewGlobalName(uint32_t id,
+ const std::string& name_str);
+
+ // Set the name for a structure member
+ std::unique_ptr<Instruction> NewMemberName(uint32_t id, uint32_t member_index,
+ const std::string& name_str);
+
+ // Return id for debug output buffer
+ uint32_t GetOutputBufferId();
+
+ // Return id for buffer uint type
+ uint32_t GetOutputBufferPtrId();
+
+ // Return binding for output buffer for current validation.
+ uint32_t GetOutputBufferBinding();
+
// Initialize state for instrumenting bindless checking
void InitializeInstDebugPrintf();
// Apply GenDebugPrintfCode to every instruction in module.
Pass::Status ProcessImpl();
- uint32_t ext_inst_printf_id_;
+ uint32_t ext_inst_printf_id_{0};
+
+ // id for output buffer variable
+ uint32_t output_buffer_id_{0};
+
+ // ptr type id for output buffer element
+ uint32_t output_buffer_ptr_id_{0};
};
} // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/instruction.cpp b/third_party/SPIRV-Tools/source/opt/instruction.cpp
index ece6baf92..aa4ae26b6 100644
--- a/third_party/SPIRV-Tools/source/opt/instruction.cpp
+++ b/third_party/SPIRV-Tools/source/opt/instruction.cpp
@@ -751,7 +751,7 @@ bool Instruction::IsOpaqueType() const {
}
bool Instruction::IsFoldable() const {
- return IsFoldableByFoldScalar() ||
+ return IsFoldableByFoldScalar() || IsFoldableByFoldVector() ||
context()->get_instruction_folder().HasConstFoldingRule(this);
}
@@ -762,7 +762,7 @@ bool Instruction::IsFoldableByFoldScalar() const {
}
Instruction* type = context()->get_def_use_mgr()->GetDef(type_id());
- if (!folder.IsFoldableType(type)) {
+ if (!folder.IsFoldableScalarType(type)) {
return false;
}
@@ -773,7 +773,29 @@ bool Instruction::IsFoldableByFoldScalar() const {
Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id);
Instruction* def_inst_type =
context()->get_def_use_mgr()->GetDef(def_inst->type_id());
- return folder.IsFoldableType(def_inst_type);
+ return folder.IsFoldableScalarType(def_inst_type);
+ });
+}
+
+bool Instruction::IsFoldableByFoldVector() const {
+ const InstructionFolder& folder = context()->get_instruction_folder();
+ if (!folder.IsFoldableOpcode(opcode())) {
+ return false;
+ }
+
+ Instruction* type = context()->get_def_use_mgr()->GetDef(type_id());
+ if (!folder.IsFoldableVectorType(type)) {
+ return false;
+ }
+
+ // Even if the type of the instruction is foldable, its operands may not be
+ // foldable (e.g., comparisons of 64bit types). Check that all operand types
+ // are foldable before accepting the instruction.
+ return WhileEachInOperand([&folder, this](const uint32_t* op_id) {
+ Instruction* def_inst = context()->get_def_use_mgr()->GetDef(*op_id);
+ Instruction* def_inst_type =
+ context()->get_def_use_mgr()->GetDef(def_inst->type_id());
+ return folder.IsFoldableVectorType(def_inst_type);
});
}
diff --git a/third_party/SPIRV-Tools/source/opt/instruction.h b/third_party/SPIRV-Tools/source/opt/instruction.h
index d50e62517..c2617fba5 100644
--- a/third_party/SPIRV-Tools/source/opt/instruction.h
+++ b/third_party/SPIRV-Tools/source/opt/instruction.h
@@ -294,6 +294,8 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// It is the responsibility of the caller to make sure
// that the instruction remains valid.
inline void AddOperand(Operand&& operand);
+ // Adds a copy of |operand| to the list of operands of this instruction.
+ inline void AddOperand(const Operand& operand);
// Gets the |index|-th logical operand as a single SPIR-V word. This method is
// not expected to be used with logical operands consisting of multiple SPIR-V
// words.
@@ -522,6 +524,10 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// constant value by |FoldScalar|.
bool IsFoldableByFoldScalar() const;
+ // Returns true if |this| is an instruction which could be folded into a
+ // constant value by |FoldVector|.
+ bool IsFoldableByFoldVector() const;
+
// Returns true if we are allowed to fold or otherwise manipulate the
// instruction that defines |id| in the given context. This includes not
// handling NaN values.
@@ -676,6 +682,10 @@ inline void Instruction::AddOperand(Operand&& operand) {
operands_.push_back(std::move(operand));
}
+inline void Instruction::AddOperand(const Operand& operand) {
+ operands_.push_back(operand);
+}
+
inline void Instruction::SetInOperand(uint32_t index,
Operand::OperandData&& data) {
SetOperand(index + TypeResultIdCount(), std::move(data));
diff --git a/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp b/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
index 9233ffd7f..b6845a599 100644
--- a/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/instrument_pass.cpp
@@ -22,9 +22,6 @@
namespace spvtools {
namespace opt {
namespace {
-// Common Parameter Positions
-constexpr int kInstCommonParamInstIdx = 0;
-constexpr int kInstCommonParamCnt = 1;
// Indices of operands in SPIR-V instructions
constexpr int kEntryPointFunctionIdInIdx = 1;
} // namespace
@@ -134,38 +131,6 @@ std::unique_ptr<Instruction> InstrumentPass::NewName(
{SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}});
}
-std::unique_ptr<Instruction> InstrumentPass::NewGlobalName(
- uint32_t id, const std::string& name_str) {
- std::string prefixed_name;
- switch (validation_id_) {
- case kInstValidationIdBindless:
- prefixed_name = "inst_bindless_";
- break;
- case kInstValidationIdBuffAddr:
- prefixed_name = "inst_buff_addr_";
- break;
- case kInstValidationIdDebugPrintf:
- prefixed_name = "inst_printf_";
- break;
- default:
- assert(false); // add new instrumentation pass here
- prefixed_name = "inst_pass_";
- break;
- }
- prefixed_name += name_str;
- return NewName(id, prefixed_name);
-}
-
-std::unique_ptr<Instruction> InstrumentPass::NewMemberName(
- uint32_t id, uint32_t member_index, const std::string& name_str) {
- return MakeUnique<Instruction>(
- context(), spv::Op::OpMemberName, 0, 0,
- std::initializer_list<Operand>{
- {SPV_OPERAND_TYPE_ID, {id}},
- {SPV_OPERAND_TYPE_LITERAL_INTEGER, {member_index}},
- {SPV_OPERAND_TYPE_LITERAL_STRING, utils::MakeVector(name_str)}});
-}
-
uint32_t InstrumentPass::Gen32BitCvtCode(uint32_t val_id,
InstructionBuilder* builder) {
// Convert integer value to 32-bit if necessary
@@ -198,52 +163,6 @@ uint32_t InstrumentPass::GenUintCastCode(uint32_t val_id,
->result_id();
}
-void InstrumentPass::GenDebugOutputFieldCode(uint32_t base_offset_id,
- uint32_t field_offset,
- uint32_t field_value_id,
- InstructionBuilder* builder) {
- // Cast value to 32-bit unsigned if necessary
- uint32_t val_id = GenUintCastCode(field_value_id, builder);
- // Store value
- Instruction* data_idx_inst = builder->AddIAdd(
- GetUintId(), base_offset_id, builder->GetUintConstantId(field_offset));
- uint32_t buf_id = GetOutputBufferId();
- uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
- Instruction* achain_inst = builder->AddAccessChain(
- buf_uint_ptr_id, buf_id,
- {builder->GetUintConstantId(kDebugOutputDataOffset),
- data_idx_inst->result_id()});
- (void)builder->AddStore(achain_inst->result_id(), val_id);
-}
-
-void InstrumentPass::GenCommonStreamWriteCode(uint32_t record_sz,
- uint32_t inst_id,
- uint32_t stage_idx,
- uint32_t base_offset_id,
- InstructionBuilder* builder) {
- // Store record size
- GenDebugOutputFieldCode(base_offset_id, kInstCommonOutSize,
- builder->GetUintConstantId(record_sz), builder);
- // Store Shader Id
- GenDebugOutputFieldCode(base_offset_id, kInstCommonOutShaderId,
- builder->GetUintConstantId(shader_id_), builder);
- // Store Instruction Idx
- GenDebugOutputFieldCode(base_offset_id, kInstCommonOutInstructionIdx, inst_id,
- builder);
- // Store Stage Idx
- GenDebugOutputFieldCode(base_offset_id, kInstCommonOutStageIdx,
- builder->GetUintConstantId(stage_idx), builder);
-}
-
-void InstrumentPass::GenFragCoordEltDebugOutputCode(
- uint32_t base_offset_id, uint32_t uint_frag_coord_id, uint32_t element,
- InstructionBuilder* builder) {
- Instruction* element_val_inst =
- builder->AddCompositeExtract(GetUintId(), uint_frag_coord_id, {element});
- GenDebugOutputFieldCode(base_offset_id, kInstFragOutFragCoordX + element,
- element_val_inst->result_id(), builder);
-}
-
uint32_t InstrumentPass::GenVarLoad(uint32_t var_id,
InstructionBuilder* builder) {
Instruction* var_inst = get_def_use_mgr()->GetDef(var_id);
@@ -252,28 +171,24 @@ uint32_t InstrumentPass::GenVarLoad(uint32_t var_id,
return load_inst->result_id();
}
-void InstrumentPass::GenBuiltinOutputCode(uint32_t builtin_id,
- uint32_t builtin_off,
- uint32_t base_offset_id,
- InstructionBuilder* builder) {
- // Load and store builtin
- uint32_t load_id = GenVarLoad(builtin_id, builder);
- GenDebugOutputFieldCode(base_offset_id, builtin_off, load_id, builder);
-}
-
-void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx,
- uint32_t base_offset_id,
- InstructionBuilder* builder) {
+uint32_t InstrumentPass::GenStageInfo(uint32_t stage_idx,
+ InstructionBuilder* builder) {
+ std::vector<uint32_t> ids(4, builder->GetUintConstantId(0));
+ ids[0] = builder->GetUintConstantId(stage_idx);
+ // %289 = OpCompositeConstruct %v4uint %uint_0 %285 %288 %uint_0
// TODO(greg-lunarg): Add support for all stages
switch (spv::ExecutionModel(stage_idx)) {
case spv::ExecutionModel::Vertex: {
// Load and store VertexId and InstanceId
- GenBuiltinOutputCode(
+ uint32_t load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::VertexIndex)),
- kInstVertOutVertexIndex, base_offset_id, builder);
- GenBuiltinOutputCode(context()->GetBuiltinInputVarId(
+ builder);
+ ids[1] = GenUintCastCode(load_id, builder);
+
+ load_id = GenVarLoad(context()->GetBuiltinInputVarId(
uint32_t(spv::BuiltIn::InstanceIndex)),
- kInstVertOutInstanceIndex, base_offset_id, builder);
+ builder);
+ ids[2] = GenUintCastCode(load_id, builder);
} break;
case spv::ExecutionModel::GLCompute:
case spv::ExecutionModel::TaskNV:
@@ -284,56 +199,50 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx,
uint32_t load_id = GenVarLoad(context()->GetBuiltinInputVarId(uint32_t(
spv::BuiltIn::GlobalInvocationId)),
builder);
- Instruction* x_inst =
- builder->AddCompositeExtract(GetUintId(), load_id, {0});
- Instruction* y_inst =
- builder->AddCompositeExtract(GetUintId(), load_id, {1});
- Instruction* z_inst =
- builder->AddCompositeExtract(GetUintId(), load_id, {2});
- GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdX,
- x_inst->result_id(), builder);
- GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdY,
- y_inst->result_id(), builder);
- GenDebugOutputFieldCode(base_offset_id, kInstCompOutGlobalInvocationIdZ,
- z_inst->result_id(), builder);
+ for (uint32_t u = 0; u < 3u; ++u) {
+ ids[u + 1] = builder->AddCompositeExtract(GetUintId(), load_id, {u})
+ ->result_id();
+ }
} break;
case spv::ExecutionModel::Geometry: {
// Load and store PrimitiveId and InvocationId.
- GenBuiltinOutputCode(
+ uint32_t load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)),
- kInstGeomOutPrimitiveId, base_offset_id, builder);
- GenBuiltinOutputCode(
+ builder);
+ ids[1] = load_id;
+ load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)),
- kInstGeomOutInvocationId, base_offset_id, builder);
+ builder);
+ ids[2] = GenUintCastCode(load_id, builder);
} break;
case spv::ExecutionModel::TessellationControl: {
// Load and store InvocationId and PrimitiveId
- GenBuiltinOutputCode(
+ uint32_t load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::InvocationId)),
- kInstTessCtlOutInvocationId, base_offset_id, builder);
- GenBuiltinOutputCode(
+ builder);
+ ids[1] = GenUintCastCode(load_id, builder);
+ load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)),
- kInstTessCtlOutPrimitiveId, base_offset_id, builder);
+ builder);
+ ids[2] = load_id;
} break;
case spv::ExecutionModel::TessellationEvaluation: {
// Load and store PrimitiveId and TessCoord.uv
- GenBuiltinOutputCode(
- context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)),
- kInstTessEvalOutPrimitiveId, base_offset_id, builder);
uint32_t load_id = GenVarLoad(
+ context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::PrimitiveId)),
+ builder);
+ ids[1] = load_id;
+ load_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::TessCoord)),
builder);
Instruction* uvec3_cast_inst =
builder->AddUnaryOp(GetVec3UintId(), spv::Op::OpBitcast, load_id);
uint32_t uvec3_cast_id = uvec3_cast_inst->result_id();
- Instruction* u_inst =
- builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {0});
- Instruction* v_inst =
- builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {1});
- GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordU,
- u_inst->result_id(), builder);
- GenDebugOutputFieldCode(base_offset_id, kInstTessEvalOutTessCoordV,
- v_inst->result_id(), builder);
+ for (uint32_t u = 0; u < 2u; ++u) {
+ ids[u + 2] =
+ builder->AddCompositeExtract(GetUintId(), uvec3_cast_id, {u})
+ ->result_id();
+ }
} break;
case spv::ExecutionModel::Fragment: {
// Load FragCoord and convert to Uint
@@ -342,9 +251,13 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx,
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::FragCoord)));
Instruction* uint_frag_coord_inst = builder->AddUnaryOp(
GetVec4UintId(), spv::Op::OpBitcast, frag_coord_inst->result_id());
- for (uint32_t u = 0; u < 2u; ++u)
- GenFragCoordEltDebugOutputCode(
- base_offset_id, uint_frag_coord_inst->result_id(), u, builder);
+ for (uint32_t u = 0; u < 2u; ++u) {
+ ids[u + 1] =
+ builder
+ ->AddCompositeExtract(GetUintId(),
+ uint_frag_coord_inst->result_id(), {u})
+ ->result_id();
+ }
} break;
case spv::ExecutionModel::RayGenerationNV:
case spv::ExecutionModel::IntersectionNV:
@@ -356,33 +269,14 @@ void InstrumentPass::GenStageStreamWriteCode(uint32_t stage_idx,
uint32_t launch_id = GenVarLoad(
context()->GetBuiltinInputVarId(uint32_t(spv::BuiltIn::LaunchIdNV)),
builder);
- Instruction* x_launch_inst =
- builder->AddCompositeExtract(GetUintId(), launch_id, {0});
- Instruction* y_launch_inst =
- builder->AddCompositeExtract(GetUintId(), launch_id, {1});
- Instruction* z_launch_inst =
- builder->AddCompositeExtract(GetUintId(), launch_id, {2});
- GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdX,
- x_launch_inst->result_id(), builder);
- GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdY,
- y_launch_inst->result_id(), builder);
- GenDebugOutputFieldCode(base_offset_id, kInstRayTracingOutLaunchIdZ,
- z_launch_inst->result_id(), builder);
+ for (uint32_t u = 0; u < 3u; ++u) {
+ ids[u + 1] = builder->AddCompositeExtract(GetUintId(), launch_id, {u})
+ ->result_id();
+ }
} break;
default: { assert(false && "unsupported stage"); } break;
}
-}
-
-void InstrumentPass::GenDebugStreamWrite(
- uint32_t instruction_idx, uint32_t stage_idx,
- const std::vector<uint32_t>& validation_ids, InstructionBuilder* builder) {
- // Call debug output function. Pass func_idx, instruction_idx and
- // validation ids as args.
- uint32_t val_id_cnt = static_cast<uint32_t>(validation_ids.size());
- std::vector<uint32_t> args = {builder->GetUintConstantId(instruction_idx)};
- (void)args.insert(args.end(), validation_ids.begin(), validation_ids.end());
- (void)builder->AddFunctionCall(
- GetVoidId(), GetStreamWriteFunctionId(stage_idx, val_id_cnt), args);
+ return builder->AddCompositeConstruct(GetVec4UintId(), ids)->result_id();
}
bool InstrumentPass::AllConstant(const std::vector<uint32_t>& ids) {
@@ -393,16 +287,9 @@ bool InstrumentPass::AllConstant(const std::vector<uint32_t>& ids) {
return true;
}
-uint32_t InstrumentPass::GenDebugDirectRead(
- const std::vector<uint32_t>& offset_ids, InstructionBuilder* builder) {
- // Call debug input function. Pass func_idx and offset ids as args.
- const uint32_t off_id_cnt = static_cast<uint32_t>(offset_ids.size());
- const uint32_t input_func_id = GetDirectReadFunctionId(off_id_cnt);
- return GenReadFunctionCall(input_func_id, offset_ids, builder);
-}
-
uint32_t InstrumentPass::GenReadFunctionCall(
- uint32_t func_id, const std::vector<uint32_t>& func_call_args,
+ uint32_t return_id, uint32_t func_id,
+ const std::vector<uint32_t>& func_call_args,
InstructionBuilder* ref_builder) {
// If optimizing direct reads and the call has already been generated,
// use its result
@@ -423,8 +310,7 @@ uint32_t InstrumentPass::GenReadFunctionCall(
builder.SetInsertPoint(insert_before);
}
uint32_t res_id =
- builder.AddFunctionCall(GetUintId(), func_id, func_call_args)
- ->result_id();
+ builder.AddFunctionCall(return_id, func_id, func_call_args)->result_id();
if (insert_in_first_block) call2id_[func_call_args] = res_id;
return res_id;
}
@@ -494,53 +380,6 @@ void InstrumentPass::UpdateSucceedingPhis(
});
}
-uint32_t InstrumentPass::GetOutputBufferPtrId() {
- if (output_buffer_ptr_id_ == 0) {
- output_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType(
- GetUintId(), spv::StorageClass::StorageBuffer);
- }
- return output_buffer_ptr_id_;
-}
-
-uint32_t InstrumentPass::GetInputBufferTypeId() {
- return (validation_id_ == kInstValidationIdBuffAddr) ? GetUint64Id()
- : GetUintId();
-}
-
-uint32_t InstrumentPass::GetInputBufferPtrId() {
- if (input_buffer_ptr_id_ == 0) {
- input_buffer_ptr_id_ = context()->get_type_mgr()->FindPointerToType(
- GetInputBufferTypeId(), spv::StorageClass::StorageBuffer);
- }
- return input_buffer_ptr_id_;
-}
-
-uint32_t InstrumentPass::GetOutputBufferBinding() {
- switch (validation_id_) {
- case kInstValidationIdBindless:
- return kDebugOutputBindingStream;
- case kInstValidationIdBuffAddr:
- return kDebugOutputBindingStream;
- case kInstValidationIdDebugPrintf:
- return kDebugOutputPrintfStream;
- default:
- assert(false && "unexpected validation id");
- }
- return 0;
-}
-
-uint32_t InstrumentPass::GetInputBufferBinding() {
- switch (validation_id_) {
- case kInstValidationIdBindless:
- return kDebugInputBindingBindless;
- case kInstValidationIdBuffAddr:
- return kDebugInputBindingBuffAddr;
- default:
- assert(false && "unexpected validation id");
- }
- return 0;
-}
-
analysis::Integer* InstrumentPass::GetInteger(uint32_t width, bool is_signed) {
analysis::Integer i(width, is_signed);
analysis::Type* type = context()->get_type_mgr()->GetRegisteredType(&i);
@@ -621,110 +460,6 @@ void InstrumentPass::AddStorageBufferExt() {
storage_buffer_ext_defined_ = true;
}
-// Return id for output buffer
-uint32_t InstrumentPass::GetOutputBufferId() {
- if (output_buffer_id_ == 0) {
- // If not created yet, create one
- analysis::DecorationManager* deco_mgr = get_decoration_mgr();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- analysis::RuntimeArray* reg_uint_rarr_ty = GetUintRuntimeArrayType(32);
- analysis::Integer* reg_uint_ty = GetInteger(32, false);
- analysis::Type* reg_buf_ty =
- GetStruct({reg_uint_ty, reg_uint_ty, reg_uint_rarr_ty});
- uint32_t obufTyId = type_mgr->GetTypeInstruction(reg_buf_ty);
- // By the Vulkan spec, a pre-existing struct containing a RuntimeArray
- // must be a block, and will therefore be decorated with Block. Therefore
- // the undecorated type returned here will not be pre-existing and can
- // safely be decorated. Since this type is now decorated, it is out of
- // sync with the TypeManager and therefore the TypeManager must be
- // invalidated after this pass.
- assert(context()->get_def_use_mgr()->NumUses(obufTyId) == 0 &&
- "used struct type returned");
- deco_mgr->AddDecoration(obufTyId, uint32_t(spv::Decoration::Block));
- deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputFlagsOffset,
- uint32_t(spv::Decoration::Offset), 0);
- deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputSizeOffset,
- uint32_t(spv::Decoration::Offset), 4);
- deco_mgr->AddMemberDecoration(obufTyId, kDebugOutputDataOffset,
- uint32_t(spv::Decoration::Offset), 8);
- uint32_t obufTyPtrId_ =
- type_mgr->FindPointerToType(obufTyId, spv::StorageClass::StorageBuffer);
- output_buffer_id_ = TakeNextId();
- std::unique_ptr<Instruction> newVarOp(new Instruction(
- context(), spv::Op::OpVariable, obufTyPtrId_, output_buffer_id_,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::StorageClass::StorageBuffer)}}}));
- context()->AddGlobalValue(std::move(newVarOp));
- context()->AddDebug2Inst(NewGlobalName(obufTyId, "OutputBuffer"));
- context()->AddDebug2Inst(NewMemberName(obufTyId, 0, "flags"));
- context()->AddDebug2Inst(NewMemberName(obufTyId, 1, "written_count"));
- context()->AddDebug2Inst(NewMemberName(obufTyId, 2, "data"));
- context()->AddDebug2Inst(NewGlobalName(output_buffer_id_, "output_buffer"));
- deco_mgr->AddDecorationVal(
- output_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_);
- deco_mgr->AddDecorationVal(output_buffer_id_,
- uint32_t(spv::Decoration::Binding),
- GetOutputBufferBinding());
- AddStorageBufferExt();
- if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
- // Add the new buffer to all entry points.
- for (auto& entry : get_module()->entry_points()) {
- entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}});
- context()->AnalyzeUses(&entry);
- }
- }
- }
- return output_buffer_id_;
-}
-
-uint32_t InstrumentPass::GetInputBufferId() {
- if (input_buffer_id_ == 0) {
- // If not created yet, create one
- analysis::DecorationManager* deco_mgr = get_decoration_mgr();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- uint32_t width = (validation_id_ == kInstValidationIdBuffAddr) ? 64u : 32u;
- analysis::Type* reg_uint_rarr_ty = GetUintRuntimeArrayType(width);
- analysis::Struct* reg_buf_ty = GetStruct({reg_uint_rarr_ty});
- uint32_t ibufTyId = type_mgr->GetTypeInstruction(reg_buf_ty);
- // By the Vulkan spec, a pre-existing struct containing a RuntimeArray
- // must be a block, and will therefore be decorated with Block. Therefore
- // the undecorated type returned here will not be pre-existing and can
- // safely be decorated. Since this type is now decorated, it is out of
- // sync with the TypeManager and therefore the TypeManager must be
- // invalidated after this pass.
- assert(context()->get_def_use_mgr()->NumUses(ibufTyId) == 0 &&
- "used struct type returned");
- deco_mgr->AddDecoration(ibufTyId, uint32_t(spv::Decoration::Block));
- deco_mgr->AddMemberDecoration(ibufTyId, 0,
- uint32_t(spv::Decoration::Offset), 0);
- uint32_t ibufTyPtrId_ =
- type_mgr->FindPointerToType(ibufTyId, spv::StorageClass::StorageBuffer);
- input_buffer_id_ = TakeNextId();
- std::unique_ptr<Instruction> newVarOp(new Instruction(
- context(), spv::Op::OpVariable, ibufTyPtrId_, input_buffer_id_,
- {{spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {uint32_t(spv::StorageClass::StorageBuffer)}}}));
- context()->AddGlobalValue(std::move(newVarOp));
- context()->AddDebug2Inst(NewGlobalName(ibufTyId, "InputBuffer"));
- context()->AddDebug2Inst(NewMemberName(ibufTyId, 0, "data"));
- context()->AddDebug2Inst(NewGlobalName(input_buffer_id_, "input_buffer"));
- deco_mgr->AddDecorationVal(
- input_buffer_id_, uint32_t(spv::Decoration::DescriptorSet), desc_set_);
- deco_mgr->AddDecorationVal(input_buffer_id_,
- uint32_t(spv::Decoration::Binding),
- GetInputBufferBinding());
- AddStorageBufferExt();
- if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
- // Add the new buffer to all entry points.
- for (auto& entry : get_module()->entry_points()) {
- entry.AddOperand({SPV_OPERAND_TYPE_ID, {input_buffer_id_}});
- context()->AnalyzeUses(&entry);
- }
- }
- }
- return input_buffer_id_;
-}
-
uint32_t InstrumentPass::GetFloatId() {
if (float_id_ == 0) {
analysis::TypeManager* type_mgr = context()->get_type_mgr();
@@ -817,159 +552,6 @@ uint32_t InstrumentPass::GetVoidId() {
return void_id_;
}
-uint32_t InstrumentPass::GetStreamWriteFunctionId(uint32_t stage_idx,
- uint32_t val_spec_param_cnt) {
- // Total param count is common params plus validation-specific
- // params
- uint32_t param_cnt = kInstCommonParamCnt + val_spec_param_cnt;
- if (param2output_func_id_[param_cnt] == 0) {
- // Create function
- param2output_func_id_[param_cnt] = TakeNextId();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
-
- const std::vector<const analysis::Type*> param_types(param_cnt,
- GetInteger(32, false));
- std::unique_ptr<Function> output_func = StartFunction(
- param2output_func_id_[param_cnt], type_mgr->GetVoidType(), param_types);
-
- std::vector<uint32_t> param_ids = AddParameters(*output_func, param_types);
-
- // Create first block
- auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
-
- InstructionBuilder builder(
- context(), &*new_blk_ptr,
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- // Gen test if debug output buffer size will not be exceeded.
- uint32_t val_spec_offset = kInstStageOutCnt;
- uint32_t obuf_record_sz = val_spec_offset + val_spec_param_cnt;
- uint32_t buf_id = GetOutputBufferId();
- uint32_t buf_uint_ptr_id = GetOutputBufferPtrId();
- Instruction* obuf_curr_sz_ac_inst = builder.AddAccessChain(
- buf_uint_ptr_id, buf_id,
- {builder.GetUintConstantId(kDebugOutputSizeOffset)});
- // Fetch the current debug buffer written size atomically, adding the
- // size of the record to be written.
- uint32_t obuf_record_sz_id = builder.GetUintConstantId(obuf_record_sz);
- uint32_t mask_none_id =
- builder.GetUintConstantId(uint32_t(spv::MemoryAccessMask::MaskNone));
- uint32_t scope_invok_id =
- builder.GetUintConstantId(uint32_t(spv::Scope::Invocation));
- Instruction* obuf_curr_sz_inst = builder.AddQuadOp(
- GetUintId(), spv::Op::OpAtomicIAdd, obuf_curr_sz_ac_inst->result_id(),
- scope_invok_id, mask_none_id, obuf_record_sz_id);
- uint32_t obuf_curr_sz_id = obuf_curr_sz_inst->result_id();
- // Compute new written size
- Instruction* obuf_new_sz_inst =
- builder.AddIAdd(GetUintId(), obuf_curr_sz_id,
- builder.GetUintConstantId(obuf_record_sz));
- // Fetch the data bound
- Instruction* obuf_bnd_inst =
- builder.AddIdLiteralOp(GetUintId(), spv::Op::OpArrayLength,
- GetOutputBufferId(), kDebugOutputDataOffset);
- // Test that new written size is less than or equal to debug output
- // data bound
- Instruction* obuf_safe_inst = builder.AddBinaryOp(
- GetBoolId(), spv::Op::OpULessThanEqual, obuf_new_sz_inst->result_id(),
- obuf_bnd_inst->result_id());
- uint32_t merge_blk_id = TakeNextId();
- uint32_t write_blk_id = TakeNextId();
- std::unique_ptr<Instruction> merge_label(NewLabel(merge_blk_id));
- std::unique_ptr<Instruction> write_label(NewLabel(write_blk_id));
- (void)builder.AddConditionalBranch(
- obuf_safe_inst->result_id(), write_blk_id, merge_blk_id, merge_blk_id,
- uint32_t(spv::SelectionControlMask::MaskNone));
- // Close safety test block and gen write block
- output_func->AddBasicBlock(std::move(new_blk_ptr));
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(write_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- // Generate common and stage-specific debug record members
- GenCommonStreamWriteCode(obuf_record_sz, param_ids[kInstCommonParamInstIdx],
- stage_idx, obuf_curr_sz_id, &builder);
- GenStageStreamWriteCode(stage_idx, obuf_curr_sz_id, &builder);
- // Gen writes of validation specific data
- for (uint32_t i = 0; i < val_spec_param_cnt; ++i) {
- GenDebugOutputFieldCode(obuf_curr_sz_id, val_spec_offset + i,
- param_ids[kInstCommonParamCnt + i], &builder);
- }
- // Close write block and gen merge block
- (void)builder.AddBranch(merge_blk_id);
- output_func->AddBasicBlock(std::move(new_blk_ptr));
- new_blk_ptr = MakeUnique<BasicBlock>(std::move(merge_label));
- builder.SetInsertPoint(&*new_blk_ptr);
- // Close merge block and function and add function to module
- (void)builder.AddNullaryOp(0, spv::Op::OpReturn);
-
- output_func->AddBasicBlock(std::move(new_blk_ptr));
- output_func->SetFunctionEnd(EndFunction());
- context()->AddFunction(std::move(output_func));
-
- std::string name("stream_write_");
- name += std::to_string(param_cnt);
-
- context()->AddDebug2Inst(
- NewGlobalName(param2output_func_id_[param_cnt], name));
- }
- return param2output_func_id_[param_cnt];
-}
-
-uint32_t InstrumentPass::GetDirectReadFunctionId(uint32_t param_cnt) {
- uint32_t func_id = param2input_func_id_[param_cnt];
- if (func_id != 0) return func_id;
- // Create input function for param_cnt.
- func_id = TakeNextId();
- analysis::Integer* uint_type = GetInteger(32, false);
- std::vector<const analysis::Type*> param_types(param_cnt, uint_type);
-
- std::unique_ptr<Function> input_func =
- StartFunction(func_id, uint_type, param_types);
- std::vector<uint32_t> param_ids = AddParameters(*input_func, param_types);
-
- // Create block
- auto new_blk_ptr = MakeUnique<BasicBlock>(NewLabel(TakeNextId()));
- InstructionBuilder builder(
- context(), &*new_blk_ptr,
- IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
- // For each offset parameter, generate new offset with parameter, adding last
- // loaded value if it exists, and load value from input buffer at new offset.
- // Return last loaded value.
- uint32_t ibuf_type_id = GetInputBufferTypeId();
- uint32_t buf_id = GetInputBufferId();
- uint32_t buf_ptr_id = GetInputBufferPtrId();
- uint32_t last_value_id = 0;
- for (uint32_t p = 0; p < param_cnt; ++p) {
- uint32_t offset_id;
- if (p == 0) {
- offset_id = param_ids[0];
- } else {
- if (ibuf_type_id != GetUintId()) {
- last_value_id =
- builder.AddUnaryOp(GetUintId(), spv::Op::OpUConvert, last_value_id)
- ->result_id();
- }
- offset_id = builder.AddIAdd(GetUintId(), last_value_id, param_ids[p])
- ->result_id();
- }
- Instruction* ac_inst = builder.AddAccessChain(
- buf_ptr_id, buf_id,
- {builder.GetUintConstantId(kDebugInputDataOffset), offset_id});
- last_value_id =
- builder.AddLoad(ibuf_type_id, ac_inst->result_id())->result_id();
- }
- (void)builder.AddUnaryOp(0, spv::Op::OpReturnValue, last_value_id);
- // Close block and function and add function to module
- input_func->AddBasicBlock(std::move(new_blk_ptr));
- input_func->SetFunctionEnd(EndFunction());
- context()->AddFunction(std::move(input_func));
-
- std::string name("direct_read_");
- name += std::to_string(param_cnt);
- context()->AddDebug2Inst(NewGlobalName(func_id, name));
-
- param2input_func_id_[param_cnt] = func_id;
- return func_id;
-}
-
void InstrumentPass::SplitBlock(
BasicBlock::iterator inst_itr, UptrVectorIterator<BasicBlock> block_itr,
std::vector<std::unique_ptr<BasicBlock>>* new_blocks) {
@@ -1071,52 +653,54 @@ bool InstrumentPass::InstProcessCallTreeFromRoots(InstProcessFunction& pfn,
}
bool InstrumentPass::InstProcessEntryPointCallTree(InstProcessFunction& pfn) {
- // Make sure all entry points have the same execution model. Do not
- // instrument if they do not.
- // TODO(greg-lunarg): Handle mixed stages. Technically, a shader module
- // can contain entry points with different execution models, although
- // such modules will likely be rare as GLSL and HLSL are geared toward
- // one model per module. In such cases we will need
- // to clone any functions which are in the call trees of entrypoints
- // with differing execution models.
- spv::ExecutionModel stage = context()->GetStage();
- // Check for supported stages
- if (stage != spv::ExecutionModel::Vertex &&
- stage != spv::ExecutionModel::Fragment &&
- stage != spv::ExecutionModel::Geometry &&
- stage != spv::ExecutionModel::GLCompute &&
- stage != spv::ExecutionModel::TessellationControl &&
- stage != spv::ExecutionModel::TessellationEvaluation &&
- stage != spv::ExecutionModel::TaskNV &&
- stage != spv::ExecutionModel::MeshNV &&
- stage != spv::ExecutionModel::RayGenerationNV &&
- stage != spv::ExecutionModel::IntersectionNV &&
- stage != spv::ExecutionModel::AnyHitNV &&
- stage != spv::ExecutionModel::ClosestHitNV &&
- stage != spv::ExecutionModel::MissNV &&
- stage != spv::ExecutionModel::CallableNV &&
- stage != spv::ExecutionModel::TaskEXT &&
- stage != spv::ExecutionModel::MeshEXT) {
- if (consumer()) {
- std::string message = "Stage not supported by instrumentation";
- consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str());
+ uint32_t stage_id;
+ if (use_stage_info_) {
+ // Make sure all entry points have the same execution model. Do not
+ // instrument if they do not.
+ // TODO(greg-lunarg): Handle mixed stages. Technically, a shader module
+ // can contain entry points with different execution models, although
+ // such modules will likely be rare as GLSL and HLSL are geared toward
+ // one model per module. In such cases we will need
+ // to clone any functions which are in the call trees of entrypoints
+ // with differing execution models.
+ spv::ExecutionModel stage = context()->GetStage();
+ // Check for supported stages
+ if (stage != spv::ExecutionModel::Vertex &&
+ stage != spv::ExecutionModel::Fragment &&
+ stage != spv::ExecutionModel::Geometry &&
+ stage != spv::ExecutionModel::GLCompute &&
+ stage != spv::ExecutionModel::TessellationControl &&
+ stage != spv::ExecutionModel::TessellationEvaluation &&
+ stage != spv::ExecutionModel::TaskNV &&
+ stage != spv::ExecutionModel::MeshNV &&
+ stage != spv::ExecutionModel::RayGenerationNV &&
+ stage != spv::ExecutionModel::IntersectionNV &&
+ stage != spv::ExecutionModel::AnyHitNV &&
+ stage != spv::ExecutionModel::ClosestHitNV &&
+ stage != spv::ExecutionModel::MissNV &&
+ stage != spv::ExecutionModel::CallableNV &&
+ stage != spv::ExecutionModel::TaskEXT &&
+ stage != spv::ExecutionModel::MeshEXT) {
+ if (consumer()) {
+ std::string message = "Stage not supported by instrumentation";
+ consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str());
+ }
+ return false;
}
- return false;
+ stage_id = static_cast<uint32_t>(stage);
+ } else {
+ stage_id = 0;
}
// Add together the roots of all entry points
std::queue<uint32_t> roots;
for (auto& e : get_module()->entry_points()) {
roots.push(e.GetSingleWordInOperand(kEntryPointFunctionIdInIdx));
}
- bool modified = InstProcessCallTreeFromRoots(pfn, &roots, uint32_t(stage));
+ bool modified = InstProcessCallTreeFromRoots(pfn, &roots, stage_id);
return modified;
}
void InstrumentPass::InitializeInstrument() {
- output_buffer_id_ = 0;
- output_buffer_ptr_id_ = 0;
- input_buffer_ptr_id_ = 0;
- input_buffer_id_ = 0;
float_id_ = 0;
v4float_id_ = 0;
uint_id_ = 0;
diff --git a/third_party/SPIRV-Tools/source/opt/instrument_pass.h b/third_party/SPIRV-Tools/source/opt/instrument_pass.h
index 4bbbb0981..e4408c93e 100644
--- a/third_party/SPIRV-Tools/source/opt/instrument_pass.h
+++ b/third_party/SPIRV-Tools/source/opt/instrument_pass.h
@@ -55,14 +55,6 @@
namespace spvtools {
namespace opt {
-namespace {
-// Validation Ids
-// These are used to identify the general validation being done and map to
-// its output buffers.
-constexpr uint32_t kInstValidationIdBindless = 0;
-constexpr uint32_t kInstValidationIdBuffAddr = 1;
-constexpr uint32_t kInstValidationIdDebugPrintf = 2;
-} // namespace
class InstrumentPass : public Pass {
using cbb_ptr = const BasicBlock*;
@@ -85,13 +77,13 @@ class InstrumentPass : public Pass {
// set |desc_set| for debug input and output buffers and writes |shader_id|
// into debug output records. |opt_direct_reads| indicates that the pass
// will see direct input buffer reads and should prepare to optimize them.
- InstrumentPass(uint32_t desc_set, uint32_t shader_id, uint32_t validation_id,
- bool opt_direct_reads = false)
+ InstrumentPass(uint32_t desc_set, uint32_t shader_id, bool opt_direct_reads,
+ bool use_stage_info)
: Pass(),
desc_set_(desc_set),
shader_id_(shader_id),
- validation_id_(validation_id),
- opt_direct_reads_(opt_direct_reads) {}
+ opt_direct_reads_(opt_direct_reads),
+ use_stage_info_(use_stage_info) {}
// Initialize state for instrumentation of module.
void InitializeInstrument();
@@ -113,108 +105,10 @@ class InstrumentPass : public Pass {
void MovePostludeCode(UptrVectorIterator<BasicBlock> ref_block_itr,
BasicBlock* new_blk_ptr);
- // Generate instructions in |builder| which will atomically fetch and
- // increment the size of the debug output buffer stream of the current
- // validation and write a record to the end of the stream, if enough space
- // in the buffer remains. The record will contain the index of the function
- // and instruction within that function |func_idx, instruction_idx| which
- // generated the record. It will also contain additional information to
- // identify the instance of the shader, depending on the stage |stage_idx|
- // of the shader. Finally, the record will contain validation-specific
- // data contained in |validation_ids| which will identify the validation
- // error as well as the values involved in the error.
- //
- // The output buffer binding written to by the code generated by the function
- // is determined by the validation id specified when each specific
- // instrumentation pass is created.
- //
- // The output buffer is a sequence of 32-bit values with the following
- // format (where all elements are unsigned 32-bit unless otherwise noted):
- //
- // Size
- // Record0
- // Record1
- // Record2
- // ...
- //
- // Size is the number of 32-bit values that have been written or
- // attempted to be written to the output buffer, excluding the Size. It is
- // initialized to 0. If the size of attempts to write the buffer exceeds
- // the actual size of the buffer, it is possible that this field can exceed
- // the actual size of the buffer.
- //
- // Each Record* is a variable-length sequence of 32-bit values with the
- // following format defined using static const offsets in the .cpp file:
- //
- // Record Size
- // Shader ID
- // Instruction Index
- // Stage
- // Stage-specific Word 0
- // Stage-specific Word 1
- // ...
- // Validation Error Code
- // Validation-specific Word 0
- // Validation-specific Word 1
- // Validation-specific Word 2
- // ...
- //
- // Each record consists of three subsections: members common across all
- // validation, members specific to the stage, and members specific to a
- // validation.
- //
- // The Record Size is the number of 32-bit words in the record, including
- // the Record Size word.
- //
- // Shader ID is a value that identifies which shader has generated the
- // validation error. It is passed when the instrumentation pass is created.
- //
- // The Instruction Index is the position of the instruction within the
- // SPIR-V file which is in error.
- //
- // The Stage is the pipeline stage which has generated the error as defined
- // by the SpvExecutionModel_ enumeration. This is used to interpret the
- // following Stage-specific words.
- //
- // The Stage-specific Words identify which invocation of the shader generated
- // the error. Every stage will write a fixed number of words. Vertex shaders
- // will write the Vertex and Instance ID. Fragment shaders will write
- // FragCoord.xy. Compute shaders will write the GlobalInvocation ID.
- // The tessellation eval shader will write the Primitive ID and TessCoords.uv.
- // The tessellation control shader and geometry shader will write the
- // Primitive ID and Invocation ID.
- //
- // The Validation Error Code specifies the exact error which has occurred.
- // These are enumerated with the kInstError* static consts. This allows
- // multiple validation layers to use the same, single output buffer.
- //
- // The Validation-specific Words are a validation-specific number of 32-bit
- // words which give further information on the validation error that
- // occurred. These are documented further in each file containing the
- // validation-specific class which derives from this base class.
- //
- // Because the code that is generated checks against the size of the buffer
- // before writing, the size of the debug out buffer can be used by the
- // validation layer to control the number of error records that are written.
- void GenDebugStreamWrite(uint32_t instruction_idx, uint32_t stage_idx,
- const std::vector<uint32_t>& validation_ids,
- InstructionBuilder* builder);
-
// Return true if all instructions in |ids| are constants or spec constants.
bool AllConstant(const std::vector<uint32_t>& ids);
- // Generate in |builder| instructions to read the unsigned integer from the
- // input buffer specified by the offsets in |offset_ids|. Given offsets
- // o0, o1, ... oN, and input buffer ibuf, return the id for the value:
- //
- // ibuf[...ibuf[ibuf[o0]+o1]...+oN]
- //
- // The binding and the format of the input buffer is determined by each
- // specific validation, which is specified at the creation of the pass.
- uint32_t GenDebugDirectRead(const std::vector<uint32_t>& offset_ids,
- InstructionBuilder* builder);
-
- uint32_t GenReadFunctionCall(uint32_t func_id,
+ uint32_t GenReadFunctionCall(uint32_t return_id, uint32_t func_id,
const std::vector<uint32_t>& args,
InstructionBuilder* builder);
@@ -242,15 +136,6 @@ class InstrumentPass : public Pass {
std::unique_ptr<Instruction> NewName(uint32_t id,
const std::string& name_str);
- // Set the name for a function or global variable, names will be
- // prefixed to identify which instrumentation pass generated them.
- std::unique_ptr<Instruction> NewGlobalName(uint32_t id,
- const std::string& name_str);
-
- // Set the name for a structure member
- std::unique_ptr<Instruction> NewMemberName(uint32_t id, uint32_t member_index,
- const std::string& name_str);
-
// Return id for 32-bit unsigned type
uint32_t GetUintId();
@@ -282,30 +167,9 @@ class InstrumentPass : public Pass {
// Return pointer to type for runtime array of uint
analysis::RuntimeArray* GetUintRuntimeArrayType(uint32_t width);
- // Return id for buffer uint type
- uint32_t GetOutputBufferPtrId();
-
- // Return id for buffer uint type
- uint32_t GetInputBufferTypeId();
-
- // Return id for buffer uint type
- uint32_t GetInputBufferPtrId();
-
- // Return binding for output buffer for current validation.
- uint32_t GetOutputBufferBinding();
-
- // Return binding for input buffer for current validation.
- uint32_t GetInputBufferBinding();
-
// Add storage buffer extension if needed
void AddStorageBufferExt();
- // Return id for debug output buffer
- uint32_t GetOutputBufferId();
-
- // Return id for debug input buffer
- uint32_t GetInputBufferId();
-
// Return id for 32-bit float type
uint32_t GetFloatId();
@@ -321,15 +185,6 @@ class InstrumentPass : public Pass {
// Return id for v3uint type
uint32_t GetVec3UintId();
- // Return id for output function. Define if it doesn't exist with
- // |val_spec_param_cnt| validation-specific uint32 parameters.
- uint32_t GetStreamWriteFunctionId(uint32_t stage_idx,
- uint32_t val_spec_param_cnt);
-
- // Return id for input function taking |param_cnt| uint32 parameters. Define
- // if it doesn't exist.
- uint32_t GetDirectReadFunctionId(uint32_t param_cnt);
-
// Split block |block_itr| into two new blocks where the second block
// contains |inst_itr| and place in |new_blocks|.
void SplitBlock(BasicBlock::iterator inst_itr,
@@ -349,40 +204,11 @@ class InstrumentPass : public Pass {
std::queue<uint32_t>* roots,
uint32_t stage_idx);
- // Gen code into |builder| to write |field_value_id| into debug output
- // buffer at |base_offset_id| + |field_offset|.
- void GenDebugOutputFieldCode(uint32_t base_offset_id, uint32_t field_offset,
- uint32_t field_value_id,
- InstructionBuilder* builder);
-
- // Generate instructions into |builder| which will write the members
- // of the debug output record common for all stages and validations at
- // |base_off|.
- void GenCommonStreamWriteCode(uint32_t record_sz, uint32_t instruction_idx,
- uint32_t stage_idx, uint32_t base_off,
- InstructionBuilder* builder);
-
- // Generate instructions into |builder| which will write
- // |uint_frag_coord_id| at |component| of the record at |base_offset_id| of
- // the debug output buffer .
- void GenFragCoordEltDebugOutputCode(uint32_t base_offset_id,
- uint32_t uint_frag_coord_id,
- uint32_t component,
- InstructionBuilder* builder);
-
// Generate instructions into |builder| which will load |var_id| and return
// its result id.
uint32_t GenVarLoad(uint32_t var_id, InstructionBuilder* builder);
- // Generate instructions into |builder| which will load the uint |builtin_id|
- // and write it into the debug output buffer at |base_off| + |builtin_off|.
- void GenBuiltinOutputCode(uint32_t builtin_id, uint32_t builtin_off,
- uint32_t base_off, InstructionBuilder* builder);
-
- // Generate instructions into |builder| which will write the |stage_idx|-
- // specific members of the debug output stream at |base_off|.
- void GenStageStreamWriteCode(uint32_t stage_idx, uint32_t base_off,
- InstructionBuilder* builder);
+ uint32_t GenStageInfo(uint32_t stage_idx, InstructionBuilder* builder);
// Return true if instruction must be in the same block that its result
// is used.
@@ -418,62 +244,47 @@ class InstrumentPass : public Pass {
// Map from instruction's unique id to offset in original file.
std::unordered_map<uint32_t, uint32_t> uid2offset_;
- // result id for OpConstantFalse
- uint32_t validation_id_;
-
- // id for output buffer variable
- uint32_t output_buffer_id_;
-
- // ptr type id for output buffer element
- uint32_t output_buffer_ptr_id_;
-
- // ptr type id for input buffer element
- uint32_t input_buffer_ptr_id_;
-
// id for debug output function
std::unordered_map<uint32_t, uint32_t> param2output_func_id_;
// ids for debug input functions
std::unordered_map<uint32_t, uint32_t> param2input_func_id_;
- // id for input buffer variable
- uint32_t input_buffer_id_;
-
// id for 32-bit float type
- uint32_t float_id_;
+ uint32_t float_id_{0};
// id for v4float type
- uint32_t v4float_id_;
+ uint32_t v4float_id_{0};
// id for v4uint type
- uint32_t v4uint_id_;
+ uint32_t v4uint_id_{0};
// id for v3uint type
- uint32_t v3uint_id_;
+ uint32_t v3uint_id_{0};
// id for 32-bit unsigned type
- uint32_t uint_id_;
+ uint32_t uint_id_{0};
// id for 64-bit unsigned type
- uint32_t uint64_id_;
+ uint32_t uint64_id_{0};
// id for 8-bit unsigned type
- uint32_t uint8_id_;
+ uint32_t uint8_id_{0};
// id for bool type
- uint32_t bool_id_;
+ uint32_t bool_id_{0};
// id for void type
- uint32_t void_id_;
+ uint32_t void_id_{0};
// boolean to remember storage buffer extension
- bool storage_buffer_ext_defined_;
+ bool storage_buffer_ext_defined_{false};
// runtime array of uint type
- analysis::RuntimeArray* uint64_rarr_ty_;
+ analysis::RuntimeArray* uint64_rarr_ty_{nullptr};
// runtime array of uint type
- analysis::RuntimeArray* uint32_rarr_ty_;
+ analysis::RuntimeArray* uint32_rarr_ty_{nullptr};
// Pre-instrumentation same-block insts
std::unordered_map<uint32_t, Instruction*> same_block_pre_;
@@ -498,11 +309,15 @@ class InstrumentPass : public Pass {
std::unordered_map<std::vector<uint32_t>, uint32_t, vector_hash_> call2id_;
// Function currently being instrumented
- Function* curr_func_;
+ Function* curr_func_{nullptr};
// Optimize direct debug input buffer reads. Specifically, move all such
// reads with constant args to first block and reuse them.
- bool opt_direct_reads_;
+ const bool opt_direct_reads_;
+
+ // Set true if the instrumentation needs to know the current stage.
+ // Note that this does not work with multi-stage modules.
+ const bool use_stage_info_;
};
} // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.cpp b/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.cpp
new file mode 100644
index 000000000..642e2d23a
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.cpp
@@ -0,0 +1,493 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/invocation_interlock_placement_pass.h"
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <functional>
+#include <optional>
+#include <queue>
+#include <stack>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "source/enum_set.h"
+#include "source/enum_string_mapping.h"
+#include "source/opt/ir_context.h"
+#include "source/opt/reflect.h"
+#include "source/spirv_target_env.h"
+#include "source/util/string_utils.h"
+
+namespace spvtools {
+namespace opt {
+
+namespace {
+constexpr uint32_t kEntryPointExecutionModelInIdx = 0;
+constexpr uint32_t kEntryPointFunctionIdInIdx = 1;
+constexpr uint32_t kFunctionCallFunctionIdInIdx = 0;
+} // namespace
+
+bool InvocationInterlockPlacementPass::hasSingleNextBlock(uint32_t block_id,
+ bool reverse_cfg) {
+ if (reverse_cfg) {
+ // We are traversing forward, so check whether there is a single successor.
+ BasicBlock* block = cfg()->block(block_id);
+
+ switch (block->tail()->opcode()) {
+ case spv::Op::OpBranchConditional:
+ return false;
+ case spv::Op::OpSwitch:
+ return block->tail()->NumInOperandWords() == 1;
+ default:
+ return !block->tail()->IsReturnOrAbort();
+ }
+ } else {
+ // We are traversing backward, so check whether there is a single
+ // predecessor.
+ return cfg()->preds(block_id).size() == 1;
+ }
+}
+
+void InvocationInterlockPlacementPass::forEachNext(
+ uint32_t block_id, bool reverse_cfg, std::function<void(uint32_t)> f) {
+ if (reverse_cfg) {
+ BasicBlock* block = cfg()->block(block_id);
+
+ block->ForEachSuccessorLabel([f](uint32_t succ_id) { f(succ_id); });
+ } else {
+ for (uint32_t pred_id : cfg()->preds(block_id)) {
+ f(pred_id);
+ }
+ }
+}
+
+void InvocationInterlockPlacementPass::addInstructionAtBlockBoundary(
+ BasicBlock* block, spv::Op opcode, bool at_end) {
+ if (at_end) {
+ assert(block->begin()->opcode() != spv::Op::OpPhi &&
+ "addInstructionAtBlockBoundary expects to be called with at_end == "
+ "true only if there is a single successor to block");
+ // Insert a begin instruction at the end of the block.
+ Instruction* begin_inst = new Instruction(context(), opcode);
+ begin_inst->InsertAfter(&*--block->tail());
+ } else {
+ assert(block->begin()->opcode() != spv::Op::OpPhi &&
+ "addInstructionAtBlockBoundary expects to be called with at_end == "
+ "false only if there is a single predecessor to block");
+ // Insert an end instruction at the beginning of the block.
+ Instruction* end_inst = new Instruction(context(), opcode);
+ end_inst->InsertBefore(&*block->begin());
+ }
+}
+
+bool InvocationInterlockPlacementPass::killDuplicateBegin(BasicBlock* block) {
+ bool found = false;
+
+ return context()->KillInstructionIf(
+ block->begin(), block->end(), [&found](Instruction* inst) {
+ if (inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT) {
+ if (found) {
+ return true;
+ }
+ found = true;
+ }
+ return false;
+ });
+}
+
+bool InvocationInterlockPlacementPass::killDuplicateEnd(BasicBlock* block) {
+ std::vector<Instruction*> to_kill;
+ block->ForEachInst([&to_kill](Instruction* inst) {
+ if (inst->opcode() == spv::Op::OpEndInvocationInterlockEXT) {
+ to_kill.push_back(inst);
+ }
+ });
+
+ if (to_kill.size() <= 1) {
+ return false;
+ }
+
+ to_kill.pop_back();
+
+ for (Instruction* inst : to_kill) {
+ context()->KillInst(inst);
+ }
+
+ return true;
+}
+
+void InvocationInterlockPlacementPass::recordBeginOrEndInFunction(
+ Function* func) {
+ if (extracted_functions_.count(func)) {
+ return;
+ }
+
+ bool had_begin = false;
+ bool had_end = false;
+
+ func->ForEachInst([this, &had_begin, &had_end](Instruction* inst) {
+ switch (inst->opcode()) {
+ case spv::Op::OpBeginInvocationInterlockEXT:
+ had_begin = true;
+ break;
+ case spv::Op::OpEndInvocationInterlockEXT:
+ had_end = true;
+ break;
+ case spv::Op::OpFunctionCall: {
+ uint32_t function_id =
+ inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx);
+ Function* inner_func = context()->GetFunction(function_id);
+ recordBeginOrEndInFunction(inner_func);
+ ExtractionResult result = extracted_functions_[inner_func];
+ had_begin = had_begin || result.had_begin;
+ had_end = had_end || result.had_end;
+ break;
+ }
+ default:
+ break;
+ }
+ });
+
+ ExtractionResult result = {had_begin, had_end};
+ extracted_functions_[func] = result;
+}
+
+bool InvocationInterlockPlacementPass::
+ removeBeginAndEndInstructionsFromFunction(Function* func) {
+ bool modified = false;
+ func->ForEachInst([this, &modified](Instruction* inst) {
+ switch (inst->opcode()) {
+ case spv::Op::OpBeginInvocationInterlockEXT:
+ context()->KillInst(inst);
+ modified = true;
+ break;
+ case spv::Op::OpEndInvocationInterlockEXT:
+ context()->KillInst(inst);
+ modified = true;
+ break;
+ default:
+ break;
+ }
+ });
+ return modified;
+}
+
+bool InvocationInterlockPlacementPass::extractInstructionsFromCalls(
+ std::vector<BasicBlock*> blocks) {
+ bool modified = false;
+
+ for (BasicBlock* block : blocks) {
+ block->ForEachInst([this, &modified](Instruction* inst) {
+ if (inst->opcode() == spv::Op::OpFunctionCall) {
+ uint32_t function_id =
+ inst->GetSingleWordInOperand(kFunctionCallFunctionIdInIdx);
+ Function* func = context()->GetFunction(function_id);
+ ExtractionResult result = extracted_functions_[func];
+
+ if (result.had_begin) {
+ Instruction* new_inst = new Instruction(
+ context(), spv::Op::OpBeginInvocationInterlockEXT);
+ new_inst->InsertBefore(inst);
+ modified = true;
+ }
+ if (result.had_end) {
+ Instruction* new_inst =
+ new Instruction(context(), spv::Op::OpEndInvocationInterlockEXT);
+ new_inst->InsertAfter(inst);
+ modified = true;
+ }
+ }
+ });
+ }
+ return modified;
+}
+
+void InvocationInterlockPlacementPass::recordExistingBeginAndEndBlock(
+ std::vector<BasicBlock*> blocks) {
+ for (BasicBlock* block : blocks) {
+ block->ForEachInst([this, block](Instruction* inst) {
+ switch (inst->opcode()) {
+ case spv::Op::OpBeginInvocationInterlockEXT:
+ begin_.insert(block->id());
+ break;
+ case spv::Op::OpEndInvocationInterlockEXT:
+ end_.insert(block->id());
+ break;
+ default:
+ break;
+ }
+ });
+ }
+}
+
+InvocationInterlockPlacementPass::BlockSet
+InvocationInterlockPlacementPass::computeReachableBlocks(
+ BlockSet& previous_inside, const BlockSet& starting_nodes,
+ bool reverse_cfg) {
+ BlockSet inside = starting_nodes;
+
+ std::deque<uint32_t> worklist;
+ worklist.insert(worklist.begin(), starting_nodes.begin(),
+ starting_nodes.end());
+
+ while (!worklist.empty()) {
+ uint32_t block_id = worklist.front();
+ worklist.pop_front();
+
+ forEachNext(block_id, reverse_cfg,
+ [&inside, &previous_inside, &worklist](uint32_t next_id) {
+ previous_inside.insert(next_id);
+ if (inside.insert(next_id).second) {
+ worklist.push_back(next_id);
+ }
+ });
+ }
+
+ return inside;
+}
+
+bool InvocationInterlockPlacementPass::removeUnneededInstructions(
+ BasicBlock* block) {
+ bool modified = false;
+ if (!predecessors_after_begin_.count(block->id()) &&
+ after_begin_.count(block->id())) {
+ // None of the previous blocks are in the critical section, but this block
+ // is. This can only happen if this block already has at least one begin
+ // instruction. Leave the first begin instruction, and remove any others.
+ modified |= killDuplicateBegin(block);
+ } else if (predecessors_after_begin_.count(block->id())) {
+ // At least one previous block is in the critical section; remove all
+ // begin instructions in this block.
+ modified |= context()->KillInstructionIf(
+ block->begin(), block->end(), [](Instruction* inst) {
+ return inst->opcode() == spv::Op::OpBeginInvocationInterlockEXT;
+ });
+ }
+
+ if (!successors_before_end_.count(block->id()) &&
+ before_end_.count(block->id())) {
+ // Same as above
+ modified |= killDuplicateEnd(block);
+ } else if (successors_before_end_.count(block->id())) {
+ modified |= context()->KillInstructionIf(
+ block->begin(), block->end(), [](Instruction* inst) {
+ return inst->opcode() == spv::Op::OpEndInvocationInterlockEXT;
+ });
+ }
+ return modified;
+}
+
+BasicBlock* InvocationInterlockPlacementPass::splitEdge(BasicBlock* block,
+ uint32_t succ_id) {
+ // Create a new block to replace the critical edge.
+ auto new_succ_temp = MakeUnique<BasicBlock>(
+ MakeUnique<Instruction>(context(), spv::Op::OpLabel, 0, TakeNextId(),
+ std::initializer_list<Operand>{}));
+ auto* new_succ = new_succ_temp.get();
+
+ // Insert the new block into the function.
+ block->GetParent()->InsertBasicBlockAfter(std::move(new_succ_temp), block);
+
+ new_succ->AddInstruction(MakeUnique<Instruction>(
+ context(), spv::Op::OpBranch, 0, 0,
+ std::initializer_list<Operand>{
+ Operand(spv_operand_type_t::SPV_OPERAND_TYPE_ID, {succ_id})}));
+
+ assert(block->tail()->opcode() == spv::Op::OpBranchConditional ||
+ block->tail()->opcode() == spv::Op::OpSwitch);
+
+ // Update the first branch to successor to instead branch to
+ // the new successor. If there are multiple edges, we arbitrarily choose the
+ // first time it appears in the list. The other edges to `succ_id` will have
+ // to be split by another call to `splitEdge`.
+ block->tail()->WhileEachInId([new_succ, succ_id](uint32_t* branch_id) {
+ if (*branch_id == succ_id) {
+ *branch_id = new_succ->id();
+ return false;
+ }
+ return true;
+ });
+
+ return new_succ;
+}
+
+bool InvocationInterlockPlacementPass::placeInstructionsForEdge(
+ BasicBlock* block, uint32_t next_id, BlockSet& inside,
+ BlockSet& previous_inside, spv::Op opcode, bool reverse_cfg) {
+ bool modified = false;
+
+ if (previous_inside.count(next_id) && !inside.count(block->id())) {
+ // This block is not in the critical section but the next has at least one
+ // other previous block that is, so this block should be enter it as well.
+ // We need to add begin or end instructions to the edge.
+
+ modified = true;
+
+ if (hasSingleNextBlock(block->id(), reverse_cfg)) {
+ // This is the only next block.
+
+ // Additionally, because `next_id` is in `previous_inside`, we know that
+ // `next_id` has at least one previous block in `inside`. And because
+ // 'block` is not in `inside`, that means the `next_id` has to have at
+ // least one other previous block in `inside`.
+
+ // This is solely for a debug assertion. It is essentially recomputing the
+ // value of `previous_inside` to verify that it was computed correctly
+ // such that the above statement is true.
+ bool next_has_previous_inside = false;
+ // By passing !reverse_cfg to forEachNext, we are actually iterating over
+ // the previous blocks.
+ forEachNext(next_id, !reverse_cfg,
+ [&next_has_previous_inside, inside](uint32_t previous_id) {
+ if (inside.count(previous_id)) {
+ next_has_previous_inside = true;
+ }
+ });
+ assert(next_has_previous_inside &&
+ "`previous_inside` must be the set of blocks with at least one "
+ "previous block in `inside`");
+
+ addInstructionAtBlockBoundary(block, opcode, reverse_cfg);
+ } else {
+ // This block has multiple next blocks. Split the edge and insert the
+ // instruction in the new next block.
+ BasicBlock* new_branch;
+ if (reverse_cfg) {
+ new_branch = splitEdge(block, next_id);
+ } else {
+ new_branch = splitEdge(cfg()->block(next_id), block->id());
+ }
+
+ auto inst = new Instruction(context(), opcode);
+ inst->InsertBefore(&*new_branch->tail());
+ }
+ }
+
+ return modified;
+}
+
+bool InvocationInterlockPlacementPass::placeInstructions(BasicBlock* block) {
+ bool modified = false;
+
+ block->ForEachSuccessorLabel([this, block, &modified](uint32_t succ_id) {
+ modified |= placeInstructionsForEdge(
+ block, succ_id, after_begin_, predecessors_after_begin_,
+ spv::Op::OpBeginInvocationInterlockEXT, /* reverse_cfg= */ true);
+ modified |= placeInstructionsForEdge(cfg()->block(succ_id), block->id(),
+ before_end_, successors_before_end_,
+ spv::Op::OpEndInvocationInterlockEXT,
+ /* reverse_cfg= */ false);
+ });
+
+ return modified;
+}
+
+bool InvocationInterlockPlacementPass::processFragmentShaderEntry(
+ Function* entry_func) {
+ bool modified = false;
+
+ // Save the original order of blocks in the function, so we don't iterate over
+ // newly-added blocks.
+ std::vector<BasicBlock*> original_blocks;
+ for (auto bi = entry_func->begin(); bi != entry_func->end(); ++bi) {
+ original_blocks.push_back(&*bi);
+ }
+
+ modified |= extractInstructionsFromCalls(original_blocks);
+ recordExistingBeginAndEndBlock(original_blocks);
+
+ after_begin_ = computeReachableBlocks(predecessors_after_begin_, begin_,
+ /* reverse_cfg= */ true);
+ before_end_ = computeReachableBlocks(successors_before_end_, end_,
+ /* reverse_cfg= */ false);
+
+ for (BasicBlock* block : original_blocks) {
+ modified |= removeUnneededInstructions(block);
+ modified |= placeInstructions(block);
+ }
+ return modified;
+}
+
+bool InvocationInterlockPlacementPass::isFragmentShaderInterlockEnabled() {
+ if (!context()->get_feature_mgr()->HasExtension(
+ kSPV_EXT_fragment_shader_interlock)) {
+ return false;
+ }
+
+ if (context()->get_feature_mgr()->HasCapability(
+ spv::Capability::FragmentShaderSampleInterlockEXT)) {
+ return true;
+ }
+
+ if (context()->get_feature_mgr()->HasCapability(
+ spv::Capability::FragmentShaderPixelInterlockEXT)) {
+ return true;
+ }
+
+ if (context()->get_feature_mgr()->HasCapability(
+ spv::Capability::FragmentShaderShadingRateInterlockEXT)) {
+ return true;
+ }
+
+ return false;
+}
+
+Pass::Status InvocationInterlockPlacementPass::Process() {
+ // Skip this pass if the necessary extension or capability is missing
+ if (!isFragmentShaderInterlockEnabled()) {
+ return Status::SuccessWithoutChange;
+ }
+
+ bool modified = false;
+
+ std::unordered_set<Function*> entry_points;
+ for (Instruction& entry_inst : context()->module()->entry_points()) {
+ uint32_t entry_id =
+ entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx);
+ entry_points.insert(context()->GetFunction(entry_id));
+ }
+
+ for (auto fi = context()->module()->begin(); fi != context()->module()->end();
+ ++fi) {
+ Function* func = &*fi;
+ recordBeginOrEndInFunction(func);
+ if (!entry_points.count(func) && extracted_functions_.count(func)) {
+ modified |= removeBeginAndEndInstructionsFromFunction(func);
+ }
+ }
+
+ for (Instruction& entry_inst : context()->module()->entry_points()) {
+ uint32_t entry_id =
+ entry_inst.GetSingleWordInOperand(kEntryPointFunctionIdInIdx);
+ Function* entry_func = context()->GetFunction(entry_id);
+
+ auto execution_model = spv::ExecutionModel(
+ entry_inst.GetSingleWordInOperand(kEntryPointExecutionModelInIdx));
+
+ if (execution_model != spv::ExecutionModel::Fragment) {
+ continue;
+ }
+
+ modified |= processFragmentShaderEntry(entry_func);
+ }
+
+ return modified ? Pass::Status::SuccessWithChange
+ : Pass::Status::SuccessWithoutChange;
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.h b/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.h
new file mode 100644
index 000000000..4e85be858
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/invocation_interlock_placement_pass.h
@@ -0,0 +1,158 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_
+#define SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_
+
+#include <algorithm>
+#include <array>
+#include <functional>
+#include <optional>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "source/enum_set.h"
+#include "source/extensions.h"
+#include "source/opt/ir_context.h"
+#include "source/opt/module.h"
+#include "source/opt/pass.h"
+#include "source/spirv_target_env.h"
+
+namespace spvtools {
+namespace opt {
+
+// This pass will ensure that an entry point will only have at most one
+// OpBeginInterlockInvocationEXT and one OpEndInterlockInvocationEXT, in that
+// order
+class InvocationInterlockPlacementPass : public Pass {
+ public:
+ InvocationInterlockPlacementPass() {}
+ InvocationInterlockPlacementPass(const InvocationInterlockPlacementPass&) =
+ delete;
+ InvocationInterlockPlacementPass(InvocationInterlockPlacementPass&&) = delete;
+
+ const char* name() const override { return "dedupe-interlock-invocation"; }
+ Status Process() override;
+
+ private:
+ using BlockSet = std::unordered_set<uint32_t>;
+
+ // Specifies whether a function originally had a begin or end instruction.
+ struct ExtractionResult {
+ bool had_begin : 1;
+ bool had_end : 2;
+ };
+
+ // Check if a block has only a single next block, depending on the directing
+ // that we are traversing the CFG. If reverse_cfg is true, we are walking
+ // forward through the CFG, and will return if the block has only one
+ // successor. Otherwise, we are walking backward through the CFG, and will
+ // return if the block has only one predecessor.
+ bool hasSingleNextBlock(uint32_t block_id, bool reverse_cfg);
+
+ // Iterate over each of a block's predecessors or successors, depending on
+ // direction. If reverse_cfg is true, we are walking forward through the CFG,
+ // and need to iterate over the successors. Otherwise, we are walking backward
+ // through the CFG, and need to iterate over the predecessors.
+ void forEachNext(uint32_t block_id, bool reverse_cfg,
+ std::function<void(uint32_t)> f);
+
+ // Add either a begin or end instruction to the edge of the basic block. If
+ // at_end is true, add the instruction to the end of the block; otherwise add
+ // the instruction to the beginning of the basic block.
+ void addInstructionAtBlockBoundary(BasicBlock* block, spv::Op opcode,
+ bool at_end);
+
+ // Remove every OpBeginInvocationInterlockEXT instruction in block after the
+ // first. Returns whether any instructions were removed.
+ bool killDuplicateBegin(BasicBlock* block);
+ // Remove every OpBeginInvocationInterlockEXT instruction in block before the
+ // last. Returns whether any instructions were removed.
+ bool killDuplicateEnd(BasicBlock* block);
+
+ // Records whether a function will potentially execute a begin or end
+ // instruction.
+ void recordBeginOrEndInFunction(Function* func);
+
+ // Recursively removes any begin or end instructions from func and any
+ // function func calls. Returns whether any instructions were removed.
+ bool removeBeginAndEndInstructionsFromFunction(Function* func);
+
+ // For every function call in any of the passed blocks, move any begin or end
+ // instructions outside of the function call. Returns whether any extractions
+ // occurred.
+ bool extractInstructionsFromCalls(std::vector<BasicBlock*> blocks);
+
+ // Finds the sets of blocks that contain OpBeginInvocationInterlockEXT and
+ // OpEndInvocationInterlockEXT, storing them in the member variables begin_
+ // and end_ respectively.
+ void recordExistingBeginAndEndBlock(std::vector<BasicBlock*> blocks);
+
+ // Compute the set of blocks including or after the barrier instruction, and
+ // the set of blocks with any previous blocks inside the barrier instruction.
+ // If reverse_cfg is true, move forward through the CFG, computing
+ // after_begin_ and predecessors_after_begin_computing after_begin_ and
+ // predecessors_after_begin_, otherwise, move backward through the CFG,
+ // computing before_end_ and successors_before_end_.
+ BlockSet computeReachableBlocks(BlockSet& in_set,
+ const BlockSet& starting_nodes,
+ bool reverse_cfg);
+
+ // Remove unneeded begin and end instructions in block.
+ bool removeUnneededInstructions(BasicBlock* block);
+
+ // Given a block which branches to multiple successors, and a specific
+ // successor, creates a new empty block, and update the branch instruction to
+ // branch to the new block instead.
+ BasicBlock* splitEdge(BasicBlock* block, uint32_t succ_id);
+
+ // For the edge from block to next_id, places a begin or end instruction on
+ // the edge, based on the direction we are walking the CFG, specified in
+ // reverse_cfg.
+ bool placeInstructionsForEdge(BasicBlock* block, uint32_t next_id,
+ BlockSet& inside, BlockSet& previous_inside,
+ spv::Op opcode, bool reverse_cfg);
+ // Calls placeInstructionsForEdge for each edge in block.
+ bool placeInstructions(BasicBlock* block);
+
+ // Processes a single fragment shader entry function.
+ bool processFragmentShaderEntry(Function* entry_func);
+
+ // Returns whether the module has the SPV_EXT_fragment_shader_interlock
+ // extension and one of the FragmentShader*InterlockEXT capabilities.
+ bool isFragmentShaderInterlockEnabled();
+
+ // Maps a function to whether that function originally held a begin or end
+ // instruction.
+ std::unordered_map<Function*, ExtractionResult> extracted_functions_;
+
+ // The set of blocks which have an OpBeginInvocationInterlockEXT instruction.
+ BlockSet begin_;
+ // The set of blocks which have an OpEndInvocationInterlockEXT instruction.
+ BlockSet end_;
+ // The set of blocks which either have a begin instruction, or have a
+ // predecessor which has a begin instruction.
+ BlockSet after_begin_;
+ // The set of blocks which either have an end instruction, or have a successor
+ // which have an end instruction.
+ BlockSet before_end_;
+ // The set of blocks which have a predecessor in after_begin_.
+ BlockSet predecessors_after_begin_;
+ // The set of blocks which have a successor in before_end_.
+ BlockSet successors_before_end_;
+};
+
+} // namespace opt
+} // namespace spvtools
+#endif // SOURCE_OPT_DEDUPE_INTERLOCK_INVOCATION_PASS_H_
diff --git a/third_party/SPIRV-Tools/source/opt/ir_builder.h b/third_party/SPIRV-Tools/source/opt/ir_builder.h
index 48e08ee7a..f3e0afcea 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_builder.h
+++ b/third_party/SPIRV-Tools/source/opt/ir_builder.h
@@ -440,6 +440,22 @@ class InstructionBuilder {
return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant);
}
+ Instruction* GetBoolConstant(bool value) {
+ analysis::Bool type;
+ uint32_t type_id = GetContext()->get_type_mgr()->GetTypeInstruction(&type);
+ analysis::Type* rebuilt_type =
+ GetContext()->get_type_mgr()->GetType(type_id);
+ uint32_t word = value;
+ const analysis::Constant* constant =
+ GetContext()->get_constant_mgr()->GetConstant(rebuilt_type, {word});
+ return GetContext()->get_constant_mgr()->GetDefiningInstruction(constant);
+ }
+
+ uint32_t GetBoolConstantId(bool value) {
+ Instruction* inst = GetBoolConstant(value);
+ return (inst != nullptr ? inst->result_id() : 0);
+ }
+
Instruction* AddCompositeExtract(uint32_t type, uint32_t id_of_composite,
const std::vector<uint32_t>& index_list) {
std::vector<Operand> operands;
diff --git a/third_party/SPIRV-Tools/source/opt/ir_context.cpp b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
index 26501c2cc..d864b7c02 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_context.cpp
+++ b/third_party/SPIRV-Tools/source/opt/ir_context.cpp
@@ -88,6 +88,9 @@ void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) {
if (set & kAnalysisDebugInfo) {
BuildDebugInfoManager();
}
+ if (set & kAnalysisLiveness) {
+ BuildLivenessManager();
+ }
}
void IRContext::InvalidateAnalysesExceptFor(
@@ -220,6 +223,28 @@ Instruction* IRContext::KillInst(Instruction* inst) {
return next_instruction;
}
+bool IRContext::KillInstructionIf(Module::inst_iterator begin,
+ Module::inst_iterator end,
+ std::function<bool(Instruction*)> condition) {
+ bool removed = false;
+ for (auto it = begin; it != end;) {
+ if (!condition(&*it)) {
+ ++it;
+ continue;
+ }
+
+ removed = true;
+ // `it` is an iterator on an intrusive list. Next is invalidated on the
+ // current node when an instruction is killed. The iterator must be moved
+ // forward before deleting the node.
+ auto instruction = &*it;
+ ++it;
+ KillInst(instruction);
+ }
+
+ return removed;
+}
+
void IRContext::CollectNonSemanticTree(
Instruction* inst, std::unordered_set<Instruction*>* to_kill) {
if (!inst->HasResultId()) return;
@@ -251,6 +276,36 @@ bool IRContext::KillDef(uint32_t id) {
return false;
}
+bool IRContext::RemoveCapability(spv::Capability capability) {
+ const bool removed = KillInstructionIf(
+ module()->capability_begin(), module()->capability_end(),
+ [capability](Instruction* inst) {
+ return static_cast<spv::Capability>(inst->GetSingleWordOperand(0)) ==
+ capability;
+ });
+
+ if (removed && feature_mgr_ != nullptr) {
+ feature_mgr_->RemoveCapability(capability);
+ }
+
+ return removed;
+}
+
+bool IRContext::RemoveExtension(Extension extension) {
+ const std::string_view extensionName = ExtensionToString(extension);
+ const bool removed = KillInstructionIf(
+ module()->extension_begin(), module()->extension_end(),
+ [&extensionName](Instruction* inst) {
+ return inst->GetOperand(0).AsString() == extensionName;
+ });
+
+ if (removed && feature_mgr_ != nullptr) {
+ feature_mgr_->RemoveExtension(extension);
+ }
+
+ return removed;
+}
+
bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) {
return ReplaceAllUsesWithPredicate(before, after,
[](Instruction*) { return true; });
@@ -718,9 +773,9 @@ void IRContext::AddCombinatorsForExtension(Instruction* extension) {
}
void IRContext::InitializeCombinators() {
- get_feature_mgr()->GetCapabilities()->ForEach([this](spv::Capability cap) {
- AddCombinatorsForCapability(uint32_t(cap));
- });
+ for (auto capability : get_feature_mgr()->GetCapabilities()) {
+ AddCombinatorsForCapability(uint32_t(capability));
+ }
for (auto& extension : module()->ext_inst_imports()) {
AddCombinatorsForExtension(&extension);
diff --git a/third_party/SPIRV-Tools/source/opt/ir_context.h b/third_party/SPIRV-Tools/source/opt/ir_context.h
index 8419ee7e9..ef7c45806 100644
--- a/third_party/SPIRV-Tools/source/opt/ir_context.h
+++ b/third_party/SPIRV-Tools/source/opt/ir_context.h
@@ -27,6 +27,7 @@
#include <vector>
#include "source/assembly_grammar.h"
+#include "source/enum_string_mapping.h"
#include "source/opt/cfg.h"
#include "source/opt/constants.h"
#include "source/opt/debug_info_manager.h"
@@ -83,7 +84,7 @@ class IRContext {
kAnalysisTypes = 1 << 15,
kAnalysisDebugInfo = 1 << 16,
kAnalysisLiveness = 1 << 17,
- kAnalysisEnd = 1 << 17
+ kAnalysisEnd = 1 << 18
};
using ProcessFunction = std::function<bool(Function*)>;
@@ -153,13 +154,19 @@ class IRContext {
inline IteratorRange<Module::inst_iterator> capabilities();
inline IteratorRange<Module::const_inst_iterator> capabilities() const;
+ // Iterators for extensions instructions contained in this module.
+ inline Module::inst_iterator extension_begin();
+ inline Module::inst_iterator extension_end();
+ inline IteratorRange<Module::inst_iterator> extensions();
+ inline IteratorRange<Module::const_inst_iterator> extensions() const;
+
// Iterators for types, constants and global variables instructions.
inline Module::inst_iterator types_values_begin();
inline Module::inst_iterator types_values_end();
inline IteratorRange<Module::inst_iterator> types_values();
inline IteratorRange<Module::const_inst_iterator> types_values() const;
- // Iterators for extension instructions contained in this module.
+ // Iterators for ext_inst import instructions contained in this module.
inline Module::inst_iterator ext_inst_import_begin();
inline Module::inst_iterator ext_inst_import_end();
inline IteratorRange<Module::inst_iterator> ext_inst_imports();
@@ -204,17 +211,26 @@ class IRContext {
// Add |capability| to the module, if it is not already enabled.
inline void AddCapability(spv::Capability capability);
-
// Appends a capability instruction to this module.
inline void AddCapability(std::unique_ptr<Instruction>&& c);
+ // Removes instruction declaring `capability` from this module.
+ // Returns true if the capability was removed, false otherwise.
+ bool RemoveCapability(spv::Capability capability);
+
// Appends an extension instruction to this module.
inline void AddExtension(const std::string& ext_name);
inline void AddExtension(std::unique_ptr<Instruction>&& e);
+ // Removes instruction declaring `extension` from this module.
+ // Returns true if the extension was removed, false otherwise.
+ bool RemoveExtension(Extension extension);
+
// Appends an extended instruction set instruction to this module.
inline void AddExtInstImport(const std::string& name);
inline void AddExtInstImport(std::unique_ptr<Instruction>&& e);
// Set the memory model for this module.
inline void SetMemoryModel(std::unique_ptr<Instruction>&& m);
+ // Get the memory model for this module.
+ inline const Instruction* GetMemoryModel() const;
// Appends an entry point instruction to this module.
inline void AddEntryPoint(std::unique_ptr<Instruction>&& e);
// Appends an execution mode instruction to this module.
@@ -238,6 +254,8 @@ class IRContext {
inline void AddType(std::unique_ptr<Instruction>&& t);
// Appends a constant, global variable, or OpUndef instruction to this module.
inline void AddGlobalValue(std::unique_ptr<Instruction>&& v);
+ // Prepends a function declaration to this module.
+ inline void AddFunctionDeclaration(std::unique_ptr<Function>&& f);
// Appends a function to this module.
inline void AddFunction(std::unique_ptr<Function>&& f);
@@ -422,6 +440,15 @@ class IRContext {
// instruction exists.
Instruction* KillInst(Instruction* inst);
+ // Deletes all the instruction in the range [`begin`; `end`[, for which the
+ // unary predicate `condition` returned true.
+ // Returns true if at least one instruction was removed, false otherwise.
+ //
+ // Pointer and iterator pointing to the deleted instructions become invalid.
+ // However other pointers and iterators are still valid.
+ bool KillInstructionIf(Module::inst_iterator begin, Module::inst_iterator end,
+ std::function<bool(Instruction*)> condition);
+
// Collects the non-semantic instruction tree that uses |inst|'s result id
// to be killed later.
void CollectNonSemanticTree(Instruction* inst,
@@ -772,7 +799,8 @@ class IRContext {
// Analyzes the features in the owned module. Builds the manager if required.
void AnalyzeFeatures() {
- feature_mgr_ = MakeUnique<FeatureManager>(grammar_);
+ feature_mgr_ =
+ std::unique_ptr<FeatureManager>(new FeatureManager(grammar_));
feature_mgr_->Analyze(module());
}
@@ -964,6 +992,22 @@ IteratorRange<Module::const_inst_iterator> IRContext::capabilities() const {
return ((const Module*)module())->capabilities();
}
+Module::inst_iterator IRContext::extension_begin() {
+ return module()->extension_begin();
+}
+
+Module::inst_iterator IRContext::extension_end() {
+ return module()->extension_end();
+}
+
+IteratorRange<Module::inst_iterator> IRContext::extensions() {
+ return module()->extensions();
+}
+
+IteratorRange<Module::const_inst_iterator> IRContext::extensions() const {
+ return ((const Module*)module())->extensions();
+}
+
Module::inst_iterator IRContext::types_values_begin() {
return module()->types_values_begin();
}
@@ -1114,6 +1158,10 @@ void IRContext::SetMemoryModel(std::unique_ptr<Instruction>&& m) {
module()->SetMemoryModel(std::move(m));
}
+const Instruction* IRContext::GetMemoryModel() const {
+ return module()->GetMemoryModel();
+}
+
void IRContext::AddEntryPoint(std::unique_ptr<Instruction>&& e) {
module()->AddEntryPoint(std::move(e));
}
@@ -1173,6 +1221,10 @@ void IRContext::AddGlobalValue(std::unique_ptr<Instruction>&& v) {
module()->AddGlobalValue(std::move(v));
}
+void IRContext::AddFunctionDeclaration(std::unique_ptr<Function>&& f) {
+ module()->AddFunctionDeclaration(std::move(f));
+}
+
void IRContext::AddFunction(std::unique_ptr<Function>&& f) {
module()->AddFunction(std::move(f));
}
diff --git a/third_party/SPIRV-Tools/source/opt/local_access_chain_convert_pass.cpp b/third_party/SPIRV-Tools/source/opt/local_access_chain_convert_pass.cpp
index 6ec0c2d38..7ba75cb7a 100644
--- a/third_party/SPIRV-Tools/source/opt/local_access_chain_convert_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/local_access_chain_convert_pass.cpp
@@ -420,13 +420,16 @@ void LocalAccessChainConvertPass::InitExtensions() {
"SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing",
"SPV_NV_fragment_shader_barycentric",
"SPV_NV_compute_shader_derivatives", "SPV_NV_shader_image_footprint",
- "SPV_NV_shading_rate", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing",
- "SPV_KHR_ray_tracing", "SPV_KHR_ray_query",
+ "SPV_NV_shading_rate", "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader",
+ "SPV_NV_ray_tracing", "SPV_KHR_ray_tracing", "SPV_KHR_ray_query",
"SPV_EXT_fragment_invocation_density", "SPV_KHR_terminate_invocation",
"SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_integer_dot_product",
"SPV_EXT_shader_image_int64", "SPV_KHR_non_semantic_info",
"SPV_KHR_uniform_group_instructions",
- "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_vulkan_memory_model"});
+ "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_vulkan_memory_model",
+ "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add",
+ "SPV_EXT_fragment_shader_interlock",
+ "SPV_NV_compute_shader_derivatives"});
}
bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds(
diff --git a/third_party/SPIRV-Tools/source/opt/local_single_block_elim_pass.cpp b/third_party/SPIRV-Tools/source/opt/local_single_block_elim_pass.cpp
index 063d1b95c..d7a9295e8 100644
--- a/third_party/SPIRV-Tools/source/opt/local_single_block_elim_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/local_single_block_elim_pass.cpp
@@ -273,11 +273,13 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
"SPV_NV_shader_image_footprint",
"SPV_NV_shading_rate",
"SPV_NV_mesh_shader",
+ "SPV_EXT_mesh_shader",
"SPV_NV_ray_tracing",
"SPV_KHR_ray_tracing",
"SPV_KHR_ray_query",
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_physical_storage_buffer",
+ "SPV_KHR_physical_storage_buffer",
"SPV_KHR_terminate_invocation",
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
@@ -285,7 +287,11 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
"SPV_KHR_non_semantic_info",
"SPV_KHR_uniform_group_instructions",
"SPV_KHR_fragment_shader_barycentric",
- "SPV_KHR_vulkan_memory_model"});
+ "SPV_KHR_vulkan_memory_model",
+ "SPV_NV_bindless_texture",
+ "SPV_EXT_shader_atomic_float_add",
+ "SPV_EXT_fragment_shader_interlock",
+ "SPV_NV_compute_shader_derivatives"});
}
} // namespace opt
diff --git a/third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp b/third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp
index a0de44c70..7cd6b0eb4 100644
--- a/third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/local_single_store_elim_pass.cpp
@@ -124,10 +124,12 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() {
"SPV_NV_shader_image_footprint",
"SPV_NV_shading_rate",
"SPV_NV_mesh_shader",
+ "SPV_EXT_mesh_shader",
"SPV_NV_ray_tracing",
"SPV_KHR_ray_query",
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_physical_storage_buffer",
+ "SPV_KHR_physical_storage_buffer",
"SPV_KHR_terminate_invocation",
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
@@ -135,7 +137,11 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() {
"SPV_KHR_non_semantic_info",
"SPV_KHR_uniform_group_instructions",
"SPV_KHR_fragment_shader_barycentric",
- "SPV_KHR_vulkan_memory_model"});
+ "SPV_KHR_vulkan_memory_model",
+ "SPV_NV_bindless_texture",
+ "SPV_EXT_shader_atomic_float_add",
+ "SPV_EXT_fragment_shader_interlock",
+ "SPV_NV_compute_shader_derivatives"});
}
bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
std::vector<Instruction*> users;
diff --git a/third_party/SPIRV-Tools/source/opt/log.h b/third_party/SPIRV-Tools/source/opt/log.h
index 68051002e..4fb66fd45 100644
--- a/third_party/SPIRV-Tools/source/opt/log.h
+++ b/third_party/SPIRV-Tools/source/opt/log.h
@@ -23,7 +23,7 @@
#include "spirv-tools/libspirv.hpp"
// Asserts the given condition is true. Otherwise, sends a message to the
-// consumer and exits the problem with failure code. Accepts the following
+// consumer and exits the program with failure code. Accepts the following
// formats:
//
// SPIRV_ASSERT(<message-consumer>, <condition-expression>);
@@ -36,7 +36,9 @@
#if !defined(NDEBUG)
#define SPIRV_ASSERT(consumer, ...) SPIRV_ASSERT_IMPL(consumer, __VA_ARGS__)
#else
-#define SPIRV_ASSERT(consumer, ...)
+// Adding a use to avoid errors in the release build related to unused
+// consumers.
+#define SPIRV_ASSERT(consumer, ...) (void)(consumer)
#endif
// Logs a debug message to the consumer. Accepts the following formats:
@@ -49,26 +51,11 @@
#if !defined(NDEBUG) && defined(SPIRV_LOG_DEBUG)
#define SPIRV_DEBUG(consumer, ...) SPIRV_DEBUG_IMPL(consumer, __VA_ARGS__)
#else
-#define SPIRV_DEBUG(consumer, ...)
+// Adding a use to avoid errors in the release build related to unused
+// consumers.
+#define SPIRV_DEBUG(consumer, ...) (void)(consumer)
#endif
-// Logs an error message to the consumer saying the given feature is
-// unimplemented.
-#define SPIRV_UNIMPLEMENTED(consumer, feature) \
- do { \
- spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
- {static_cast<size_t>(__LINE__), 0, 0}, \
- "unimplemented: " feature); \
- } while (0)
-
-// Logs an error message to the consumer saying the code location
-// should be unreachable.
-#define SPIRV_UNREACHABLE(consumer) \
- do { \
- spvtools::Log(consumer, SPV_MSG_INTERNAL_ERROR, __FILE__, \
- {static_cast<size_t>(__LINE__), 0, 0}, "unreachable"); \
- } while (0)
-
// Helper macros for concatenating arguments.
#define SPIRV_CONCATENATE(a, b) SPIRV_CONCATENATE_(a, b)
#define SPIRV_CONCATENATE_(a, b) a##b
diff --git a/third_party/SPIRV-Tools/source/opt/mem_pass.cpp b/third_party/SPIRV-Tools/source/opt/mem_pass.cpp
index 9f9578569..9972c4f75 100644
--- a/third_party/SPIRV-Tools/source/opt/mem_pass.cpp
+++ b/third_party/SPIRV-Tools/source/opt/mem_pass.cpp
@@ -76,6 +76,11 @@ bool MemPass::IsNonPtrAccessChain(const spv::Op opcode) const {
bool MemPass::IsPtr(uint32_t ptrId) {
uint32_t varId = ptrId;
Instruction* ptrInst = get_def_use_mgr()->GetDef(varId);
+ if (ptrInst->opcode() == spv::Op::OpFunction) {
+ // A function is not a pointer, but it's return type could be, which will
+ // erroneously lead to this function returning true later on
+ return false;
+ }
while (ptrInst->opcode() == spv::Op::OpCopyObject) {
varId = ptrInst->GetSingleWordInOperand(kCopyObjectOperandInIdx);
ptrInst = get_def_use_mgr()->GetDef(varId);
diff --git a/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.cpp b/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.cpp
new file mode 100644
index 000000000..dd79b6283
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.cpp
@@ -0,0 +1,103 @@
+// Copyright (c) 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "modify_maximal_reconvergence.h"
+
+#include "source/opt/ir_context.h"
+#include "source/util/make_unique.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status ModifyMaximalReconvergence::Process() {
+ bool changed = false;
+ if (add_) {
+ changed = AddMaximalReconvergence();
+ } else {
+ changed = RemoveMaximalReconvergence();
+ }
+ return changed ? Pass::Status::SuccessWithChange
+ : Pass::Status::SuccessWithoutChange;
+}
+
+bool ModifyMaximalReconvergence::AddMaximalReconvergence() {
+ bool changed = false;
+ bool has_extension = false;
+ bool has_shader =
+ context()->get_feature_mgr()->HasCapability(spv::Capability::Shader);
+ for (auto extension : context()->extensions()) {
+ if (extension.GetOperand(0).AsString() == "SPV_KHR_maximal_reconvergence") {
+ has_extension = true;
+ break;
+ }
+ }
+
+ std::unordered_set<uint32_t> entry_points_with_mode;
+ for (auto mode : get_module()->execution_modes()) {
+ if (spv::ExecutionMode(mode.GetSingleWordInOperand(1)) ==
+ spv::ExecutionMode::MaximallyReconvergesKHR) {
+ entry_points_with_mode.insert(mode.GetSingleWordInOperand(0));
+ }
+ }
+
+ for (auto entry_point : get_module()->entry_points()) {
+ const uint32_t id = entry_point.GetSingleWordInOperand(1);
+ if (!entry_points_with_mode.count(id)) {
+ changed = true;
+ if (!has_extension) {
+ context()->AddExtension("SPV_KHR_maximal_reconvergence");
+ has_extension = true;
+ }
+ if (!has_shader) {
+ context()->AddCapability(spv::Capability::Shader);
+ has_shader = true;
+ }
+ context()->AddExecutionMode(MakeUnique<Instruction>(
+ context(), spv::Op::OpExecutionMode, 0, 0,
+ std::initializer_list<Operand>{
+ {SPV_OPERAND_TYPE_ID, {id}},
+ {SPV_OPERAND_TYPE_EXECUTION_MODE,
+ {static_cast<uint32_t>(
+ spv::ExecutionMode::MaximallyReconvergesKHR)}}}));
+ entry_points_with_mode.insert(id);
+ }
+ }
+
+ return changed;
+}
+
+bool ModifyMaximalReconvergence::RemoveMaximalReconvergence() {
+ bool changed = false;
+ std::vector<Instruction*> to_remove;
+ Instruction* mode = &*get_module()->execution_mode_begin();
+ while (mode) {
+ if (mode->opcode() != spv::Op::OpExecutionMode &&
+ mode->opcode() != spv::Op::OpExecutionModeId) {
+ break;
+ }
+ if (spv::ExecutionMode(mode->GetSingleWordInOperand(1)) ==
+ spv::ExecutionMode::MaximallyReconvergesKHR) {
+ mode = context()->KillInst(mode);
+ changed = true;
+ } else {
+ mode = mode->NextNode();
+ }
+ }
+
+ changed |=
+ context()->RemoveExtension(Extension::kSPV_KHR_maximal_reconvergence);
+ return changed;
+}
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.h b/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.h
new file mode 100644
index 000000000..8d9a698e9
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/modify_maximal_reconvergence.h
@@ -0,0 +1,53 @@
+// Copyright (c) 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_
+#define LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_
+
+#include "pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// Modifies entry points to either add or remove MaximallyReconvergesKHR
+//
+// This pass will either add or remove MaximallyReconvergesKHR to all entry
+// points in the module. When adding the execution mode, it does not attempt to
+// determine whether any ray tracing invocation repack instructions might be
+// executed because it is a runtime restriction. That is left to the user.
+class ModifyMaximalReconvergence : public Pass {
+ public:
+ const char* name() const override { return "modify-maximal-reconvergence"; }
+ Status Process() override;
+
+ explicit ModifyMaximalReconvergence(bool add = true) : Pass(), add_(add) {}
+
+ IRContext::Analysis GetPreservedAnalyses() override {
+ return IRContext::kAnalysisDefUse |
+ IRContext::kAnalysisInstrToBlockMapping |
+ IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators |
+ IRContext::kAnalysisCFG | IRContext::kAnalysisNameMap |
+ IRContext::kAnalysisConstants | IRContext::kAnalysisTypes;
+ }
+
+ private:
+ bool AddMaximalReconvergence();
+ bool RemoveMaximalReconvergence();
+
+ bool add_;
+};
+} // namespace opt
+} // namespace spvtools
+
+#endif // LIBSPIRV_OPT_MODIFY_MAXIMAL_RECONVERGENCE_H_
diff --git a/third_party/SPIRV-Tools/source/opt/module.h b/third_party/SPIRV-Tools/source/opt/module.h
index ed2f3454e..98c16dc4c 100644
--- a/third_party/SPIRV-Tools/source/opt/module.h
+++ b/third_party/SPIRV-Tools/source/opt/module.h
@@ -17,6 +17,7 @@
#include <functional>
#include <memory>
+#include <string_view>
#include <unordered_map>
#include <utility>
#include <vector>
@@ -119,6 +120,9 @@ class Module {
// Appends a constant, global variable, or OpUndef instruction to this module.
inline void AddGlobalValue(std::unique_ptr<Instruction> v);
+ // Prepends a function declaration to this module.
+ inline void AddFunctionDeclaration(std::unique_ptr<Function> f);
+
// Appends a function to this module.
inline void AddFunction(std::unique_ptr<Function> f);
@@ -379,6 +383,11 @@ inline void Module::AddGlobalValue(std::unique_ptr<Instruction> v) {
types_values_.push_back(std::move(v));
}
+inline void Module::AddFunctionDeclaration(std::unique_ptr<Function> f) {
+ // function declarations must come before function definitions.
+ functions_.emplace(functions_.begin(), std::move(f));
+}
+
inline void Module::AddFunction(std::unique_ptr<Function> f) {
functions_.emplace_back(std::move(f));
}
diff --git a/third_party/SPIRV-Tools/source/opt/optimizer.cpp b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
index 46a92dd90..c4c2b0f55 100644
--- a/third_party/SPIRV-Tools/source/opt/optimizer.cpp
+++ b/third_party/SPIRV-Tools/source/opt/optimizer.cpp
@@ -15,6 +15,7 @@
#include "spirv-tools/optimizer.hpp"
#include <cassert>
+#include <charconv>
#include <memory>
#include <string>
#include <unordered_map>
@@ -32,6 +33,15 @@
namespace spvtools {
+std::vector<std::string> GetVectorOfStrings(const char** strings,
+ const size_t string_count) {
+ std::vector<std::string> result;
+ for (uint32_t i = 0; i < string_count; i++) {
+ result.emplace_back(strings[i]);
+ }
+ return result;
+}
+
struct Optimizer::PassToken::Impl {
Impl(std::unique_ptr<opt::Pass> p) : pass(std::move(p)) {}
@@ -109,7 +119,7 @@ Optimizer& Optimizer::RegisterPass(PassToken&& p) {
// The legalization problem is essentially a very general copy propagation
// problem. The optimization we use are all used to either do copy propagation
// or enable more copy propagation.
-Optimizer& Optimizer::RegisterLegalizationPasses() {
+Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) {
return
// Wrap OpKill instructions so all other code can be inlined.
RegisterPass(CreateWrapOpKillPass())
@@ -129,16 +139,16 @@ Optimizer& Optimizer::RegisterLegalizationPasses() {
// Propagate the value stored to the loads in very simple cases.
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
.RegisterPass(CreateLocalSingleStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
// Split up aggregates so they are easier to deal with.
.RegisterPass(CreateScalarReplacementPass(0))
// Remove loads and stores so everything is in intermediate values.
// Takes care of copy propagation of non-members.
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
.RegisterPass(CreateLocalSingleStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateLocalMultiStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
// Propagate constants to get as many constant conditions on branches
// as possible.
.RegisterPass(CreateCCPPass())
@@ -147,7 +157,7 @@ Optimizer& Optimizer::RegisterLegalizationPasses() {
// Copy propagate members. Cleans up code sequences generated by
// scalar replacement. Also important for removing OpPhi nodes.
.RegisterPass(CreateSimplificationPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateCopyPropagateArraysPass())
// May need loop unrolling here see
// https://github.com/Microsoft/DirectXShaderCompiler/pull/930
@@ -156,30 +166,36 @@ Optimizer& Optimizer::RegisterLegalizationPasses() {
.RegisterPass(CreateVectorDCEPass())
.RegisterPass(CreateDeadInsertElimPass())
.RegisterPass(CreateReduceLoadSizePass())
- .RegisterPass(CreateAggressiveDCEPass())
- .RegisterPass(CreateInterpolateFixupPass());
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
+ .RegisterPass(CreateRemoveUnusedInterfaceVariablesPass())
+ .RegisterPass(CreateInterpolateFixupPass())
+ .RegisterPass(CreateInvocationInterlockPlacementPass());
}
-Optimizer& Optimizer::RegisterPerformancePasses() {
+Optimizer& Optimizer::RegisterLegalizationPasses() {
+ return RegisterLegalizationPasses(false);
+}
+
+Optimizer& Optimizer::RegisterPerformancePasses(bool preserve_interface) {
return RegisterPass(CreateWrapOpKillPass())
.RegisterPass(CreateDeadBranchElimPass())
.RegisterPass(CreateMergeReturnPass())
.RegisterPass(CreateInlineExhaustivePass())
.RegisterPass(CreateEliminateDeadFunctionsPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreatePrivateToLocalPass())
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
.RegisterPass(CreateLocalSingleStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateScalarReplacementPass())
.RegisterPass(CreateLocalAccessChainConvertPass())
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
.RegisterPass(CreateLocalSingleStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateLocalMultiStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateCCPPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateLoopUnrollPass(true))
.RegisterPass(CreateDeadBranchElimPass())
.RegisterPass(CreateRedundancyEliminationPass())
@@ -189,9 +205,9 @@ Optimizer& Optimizer::RegisterPerformancePasses() {
.RegisterPass(CreateLocalAccessChainConvertPass())
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
.RegisterPass(CreateLocalSingleStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateSSARewritePass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateVectorDCEPass())
.RegisterPass(CreateDeadInsertElimPass())
.RegisterPass(CreateDeadBranchElimPass())
@@ -199,7 +215,7 @@ Optimizer& Optimizer::RegisterPerformancePasses() {
.RegisterPass(CreateIfConversionPass())
.RegisterPass(CreateCopyPropagateArraysPass())
.RegisterPass(CreateReduceLoadSizePass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateBlockMergePass())
.RegisterPass(CreateRedundancyEliminationPass())
.RegisterPass(CreateDeadBranchElimPass())
@@ -207,7 +223,11 @@ Optimizer& Optimizer::RegisterPerformancePasses() {
.RegisterPass(CreateSimplificationPass());
}
-Optimizer& Optimizer::RegisterSizePasses() {
+Optimizer& Optimizer::RegisterPerformancePasses() {
+ return RegisterPerformancePasses(false);
+}
+
+Optimizer& Optimizer::RegisterSizePasses(bool preserve_interface) {
return RegisterPass(CreateWrapOpKillPass())
.RegisterPass(CreateDeadBranchElimPass())
.RegisterPass(CreateMergeReturnPass())
@@ -224,12 +244,12 @@ Optimizer& Optimizer::RegisterSizePasses() {
.RegisterPass(CreateLocalSingleStoreElimPass())
.RegisterPass(CreateIfConversionPass())
.RegisterPass(CreateSimplificationPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateDeadBranchElimPass())
.RegisterPass(CreateBlockMergePass())
.RegisterPass(CreateLocalAccessChainConvertPass())
.RegisterPass(CreateLocalSingleBlockLoadStoreElimPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateCopyPropagateArraysPass())
.RegisterPass(CreateVectorDCEPass())
.RegisterPass(CreateDeadInsertElimPass())
@@ -239,13 +259,20 @@ Optimizer& Optimizer::RegisterSizePasses() {
.RegisterPass(CreateLocalMultiStoreElimPass())
.RegisterPass(CreateRedundancyEliminationPass())
.RegisterPass(CreateSimplificationPass())
- .RegisterPass(CreateAggressiveDCEPass())
+ .RegisterPass(CreateAggressiveDCEPass(preserve_interface))
.RegisterPass(CreateCFGCleanupPass());
}
+Optimizer& Optimizer::RegisterSizePasses() { return RegisterSizePasses(false); }
+
bool Optimizer::RegisterPassesFromFlags(const std::vector<std::string>& flags) {
+ return RegisterPassesFromFlags(flags, false);
+}
+
+bool Optimizer::RegisterPassesFromFlags(const std::vector<std::string>& flags,
+ bool preserve_interface) {
for (const auto& flag : flags) {
- if (!RegisterPassFromFlag(flag)) {
+ if (!RegisterPassFromFlag(flag, preserve_interface)) {
return false;
}
}
@@ -269,6 +296,11 @@ bool Optimizer::FlagHasValidForm(const std::string& flag) const {
}
bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
+ return RegisterPassFromFlag(flag, false);
+}
+
+bool Optimizer::RegisterPassFromFlag(const std::string& flag,
+ bool preserve_interface) {
if (!FlagHasValidForm(flag)) {
return false;
}
@@ -330,7 +362,7 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
} else if (pass_name == "descriptor-scalar-replacement") {
RegisterPass(CreateDescriptorScalarReplacementPass());
} else if (pass_name == "eliminate-dead-code-aggressive") {
- RegisterPass(CreateAggressiveDCEPass());
+ RegisterPass(CreateAggressiveDCEPass(preserve_interface));
} else if (pass_name == "eliminate-insert-extract") {
RegisterPass(CreateInsertExtractElimPass());
} else if (pass_name == "eliminate-local-single-block") {
@@ -419,32 +451,26 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
RegisterPass(CreateWorkaround1209Pass());
} else if (pass_name == "replace-invalid-opcode") {
RegisterPass(CreateReplaceInvalidOpcodePass());
- } else if (pass_name == "inst-bindless-check") {
- RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false));
+ } else if (pass_name == "inst-bindless-check" ||
+ pass_name == "inst-desc-idx-check" ||
+ pass_name == "inst-buff-oob-check") {
+ // preserve legacy names
+ RegisterPass(CreateInstBindlessCheckPass(23));
RegisterPass(CreateSimplificationPass());
RegisterPass(CreateDeadBranchElimPass());
RegisterPass(CreateBlockMergePass());
- RegisterPass(CreateAggressiveDCEPass(true));
- } else if (pass_name == "inst-desc-idx-check") {
- RegisterPass(CreateInstBindlessCheckPass(7, 23, true, true));
- RegisterPass(CreateSimplificationPass());
- RegisterPass(CreateDeadBranchElimPass());
- RegisterPass(CreateBlockMergePass());
- RegisterPass(CreateAggressiveDCEPass(true));
- } else if (pass_name == "inst-buff-oob-check") {
- RegisterPass(CreateInstBindlessCheckPass(7, 23, false, false, true, true));
- RegisterPass(CreateSimplificationPass());
- RegisterPass(CreateDeadBranchElimPass());
- RegisterPass(CreateBlockMergePass());
- RegisterPass(CreateAggressiveDCEPass(true));
} else if (pass_name == "inst-buff-addr-check") {
- RegisterPass(CreateInstBuffAddrCheckPass(7, 23));
- RegisterPass(CreateAggressiveDCEPass(true));
+ RegisterPass(CreateInstBuffAddrCheckPass(23));
} else if (pass_name == "convert-relaxed-to-half") {
RegisterPass(CreateConvertRelaxedToHalfPass());
} else if (pass_name == "relax-float-ops") {
RegisterPass(CreateRelaxFloatOpsPass());
} else if (pass_name == "inst-debug-printf") {
+ // This private option is not for user consumption.
+ // It is here to assist in debugging and fixing the debug printf
+ // instrumentation pass.
+ // For users who wish to utilize debug printf, see the white paper at
+ // https://www.lunarg.com/wp-content/uploads/2021/08/Using-Debug-Printf-02August2021.pdf
RegisterPass(CreateInstDebugPrintfPass(7, 23));
} else if (pass_name == "simplify-instructions") {
RegisterPass(CreateSimplificationPass());
@@ -507,11 +533,11 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
} else if (pass_name == "fix-storage-class") {
RegisterPass(CreateFixStorageClassPass());
} else if (pass_name == "O") {
- RegisterPerformancePasses();
+ RegisterPerformancePasses(preserve_interface);
} else if (pass_name == "Os") {
- RegisterSizePasses();
+ RegisterSizePasses(preserve_interface);
} else if (pass_name == "legalize-hlsl") {
- RegisterLegalizationPasses();
+ RegisterLegalizationPasses(preserve_interface);
} else if (pass_name == "remove-unused-interface-variables") {
RegisterPass(CreateRemoveUnusedInterfaceVariablesPass());
} else if (pass_name == "graphics-robust-access") {
@@ -548,6 +574,58 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
pass_args.c_str());
return false;
}
+ } else if (pass_name == "switch-descriptorset") {
+ if (pass_args.size() == 0) {
+ Error(consumer(), nullptr, {},
+ "--switch-descriptorset requires a from:to argument.");
+ return false;
+ }
+ uint32_t from_set = 0, to_set = 0;
+ const char* start = pass_args.data();
+ const char* end = pass_args.data() + pass_args.size();
+
+ auto result = std::from_chars(start, end, from_set);
+ if (result.ec != std::errc()) {
+ Errorf(consumer(), nullptr, {},
+ "Invalid argument for --switch-descriptorset: %s",
+ pass_args.c_str());
+ return false;
+ }
+ start = result.ptr;
+ if (start[0] != ':') {
+ Errorf(consumer(), nullptr, {},
+ "Invalid argument for --switch-descriptorset: %s",
+ pass_args.c_str());
+ return false;
+ }
+ start++;
+ result = std::from_chars(start, end, to_set);
+ if (result.ec != std::errc() || result.ptr != end) {
+ Errorf(consumer(), nullptr, {},
+ "Invalid argument for --switch-descriptorset: %s",
+ pass_args.c_str());
+ return false;
+ }
+ RegisterPass(CreateSwitchDescriptorSetPass(from_set, to_set));
+ } else if (pass_name == "modify-maximal-reconvergence") {
+ if (pass_args.size() == 0) {
+ Error(consumer(), nullptr, {},
+ "--modify-maximal-reconvergence requires an argument");
+ return false;
+ }
+ if (pass_args == "add") {
+ RegisterPass(CreateModifyMaximalReconvergencePass(true));
+ } else if (pass_args == "remove") {
+ RegisterPass(CreateModifyMaximalReconvergencePass(false));
+ } else {
+ Errorf(consumer(), nullptr, {},
+ "Invalid argument for --modify-maximal-reconvergence: %s (must be "
+ "'add' or 'remove')",
+ pass_args.c_str());
+ return false;
+ }
+ } else if (pass_name == "trim-capabilities") {
+ RegisterPass(CreateTrimCapabilitiesPass());
} else {
Errorf(consumer(), nullptr, {},
"Unknown flag '--%s'. Use --help for a list of valid flags",
@@ -945,14 +1023,9 @@ Optimizer::PassToken CreateUpgradeMemoryModelPass() {
MakeUnique<opt::UpgradeMemoryModel>());
}
-Optimizer::PassToken CreateInstBindlessCheckPass(
- uint32_t desc_set, uint32_t shader_id, bool desc_length_enable,
- bool desc_init_enable, bool buff_oob_enable, bool texbuff_oob_enable) {
+Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id) {
return MakeUnique<Optimizer::PassToken::Impl>(
- MakeUnique<opt::InstBindlessCheckPass>(
- desc_set, shader_id, desc_length_enable, desc_init_enable,
- buff_oob_enable, texbuff_oob_enable,
- desc_length_enable || desc_init_enable || buff_oob_enable));
+ MakeUnique<opt::InstBindlessCheckPass>(shader_id));
}
Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set,
@@ -961,10 +1034,9 @@ Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set,
MakeUnique<opt::InstDebugPrintfPass>(desc_set, shader_id));
}
-Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t desc_set,
- uint32_t shader_id) {
+Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id) {
return MakeUnique<Optimizer::PassToken::Impl>(
- MakeUnique<opt::InstBuffAddrCheckPass>(desc_set, shader_id));
+ MakeUnique<opt::InstBuffAddrCheckPass>(shader_id));
}
Optimizer::PassToken CreateConvertRelaxedToHalfPass() {
@@ -1074,6 +1146,26 @@ Optimizer::PassToken CreateFixFuncCallArgumentsPass() {
return MakeUnique<Optimizer::PassToken::Impl>(
MakeUnique<opt::FixFuncCallArgumentsPass>());
}
+
+Optimizer::PassToken CreateTrimCapabilitiesPass() {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::TrimCapabilitiesPass>());
+}
+
+Optimizer::PassToken CreateSwitchDescriptorSetPass(uint32_t from, uint32_t to) {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::SwitchDescriptorSetPass>(from, to));
+}
+
+Optimizer::PassToken CreateInvocationInterlockPlacementPass() {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::InvocationInterlockPlacementPass>());
+}
+
+Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add) {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::ModifyMaximalReconvergence>(add));
+}
} // namespace spvtools
extern "C" {
@@ -1122,13 +1214,19 @@ SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassFromFlag(
SPIRV_TOOLS_EXPORT bool spvOptimizerRegisterPassesFromFlags(
spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) {
- std::vector<std::string> opt_flags;
- for (uint32_t i = 0; i < flag_count; i++) {
- opt_flags.emplace_back(flags[i]);
- }
+ std::vector<std::string> opt_flags =
+ spvtools::GetVectorOfStrings(flags, flag_count);
+ return reinterpret_cast<spvtools::Optimizer*>(optimizer)
+ ->RegisterPassesFromFlags(opt_flags, false);
+}
- return reinterpret_cast<spvtools::Optimizer*>(optimizer)->
- RegisterPassesFromFlags(opt_flags);
+SPIRV_TOOLS_EXPORT bool
+spvOptimizerRegisterPassesFromFlagsWhilePreservingTheInterface(
+ spv_optimizer_t* optimizer, const char** flags, const size_t flag_count) {
+ std::vector<std::string> opt_flags =
+ spvtools::GetVectorOfStrings(flags, flag_count);
+ return reinterpret_cast<spvtools::Optimizer*>(optimizer)
+ ->RegisterPassesFromFlags(opt_flags, true);
}
SPIRV_TOOLS_EXPORT
diff --git a/third_party/SPIRV-Tools/source/opt/passes.h b/third_party/SPIRV-Tools/source/opt/passes.h
index eb3b1e5d3..9d027fbf4 100644
--- a/third_party/SPIRV-Tools/source/opt/passes.h
+++ b/third_party/SPIRV-Tools/source/opt/passes.h
@@ -53,6 +53,7 @@
#include "source/opt/inst_debug_printf_pass.h"
#include "source/opt/interface_var_sroa.h"
#include "source/opt/interp_fixup_pass.h"
+#include "source/opt/invocation_interlock_placement_pass.h"
#include "source/opt/licm_pass.h"
#include "source/opt/local_access_chain_convert_pass.h"
#include "source/opt/local_redundancy_elimination.h"
@@ -64,6 +65,7 @@
#include "source/opt/loop_unroller.h"
#include "source/opt/loop_unswitch_pass.h"
#include "source/opt/merge_return_pass.h"
+#include "source/opt/modify_maximal_reconvergence.h"
#include "source/opt/null_pass.h"
#include "source/opt/private_to_local_pass.h"
#include "source/opt/reduce_load_size.h"
@@ -82,6 +84,8 @@
#include "source/opt/strength_reduction_pass.h"
#include "source/opt/strip_debug_info_pass.h"
#include "source/opt/strip_nonsemantic_info_pass.h"
+#include "source/opt/switch_descriptorset_pass.h"
+#include "source/opt/trim_capabilities_pass.h"
#include "source/opt/unify_const_pass.h"
#include "source/opt/upgrade_memory_model.h"
#include "source/opt/vector_dce.h"
diff --git a/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.cpp b/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.cpp
new file mode 100644
index 000000000..f07c91757
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.cpp
@@ -0,0 +1,46 @@
+// Copyright (c) 2023 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/switch_descriptorset_pass.h"
+
+#include "source/opt/ir_builder.h"
+#include "source/util/string_utils.h"
+
+namespace spvtools {
+namespace opt {
+
+Pass::Status SwitchDescriptorSetPass::Process() {
+ Status status = Status::SuccessWithoutChange;
+ auto* deco_mgr = context()->get_decoration_mgr();
+
+ for (Instruction& var : context()->types_values()) {
+ if (var.opcode() != spv::Op::OpVariable) {
+ continue;
+ }
+ auto decos = deco_mgr->GetDecorationsFor(var.result_id(), false);
+ for (const auto& deco : decos) {
+ spv::Decoration d = spv::Decoration(deco->GetSingleWordInOperand(1u));
+ if (d == spv::Decoration::DescriptorSet &&
+ deco->GetSingleWordInOperand(2u) == ds_from_) {
+ deco->SetInOperand(2u, {ds_to_});
+ status = Status::SuccessWithChange;
+ break;
+ }
+ }
+ }
+ return status;
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.h b/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.h
new file mode 100644
index 000000000..2084e9cda
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/switch_descriptorset_pass.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2023 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <cstdio>
+#include <memory>
+#include <queue>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "source/opt/pass.h"
+
+namespace spvtools {
+namespace opt {
+
+// See optimizer.hpp for documentation.
+class SwitchDescriptorSetPass : public Pass {
+ public:
+ SwitchDescriptorSetPass(uint32_t ds_from, uint32_t ds_to)
+ : ds_from_(ds_from), ds_to_(ds_to) {}
+
+ const char* name() const override { return "switch-descriptorset"; }
+
+ Status Process() override;
+
+ IRContext::Analysis GetPreservedAnalyses() override {
+ // this pass preserves everything except decorations
+ uint32_t mask = ((IRContext::kAnalysisEnd << 1) - 1);
+ mask &= ~static_cast<uint32_t>(IRContext::kAnalysisDecorations);
+ return static_cast<IRContext::Analysis>(mask);
+ }
+
+ private:
+ uint32_t ds_from_;
+ uint32_t ds_to_;
+};
+
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.cpp b/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.cpp
new file mode 100644
index 000000000..24f9e4670
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.cpp
@@ -0,0 +1,649 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "source/opt/trim_capabilities_pass.h"
+
+#include <algorithm>
+#include <array>
+#include <cassert>
+#include <functional>
+#include <optional>
+#include <queue>
+#include <stack>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include "source/enum_set.h"
+#include "source/enum_string_mapping.h"
+#include "source/opt/ir_context.h"
+#include "source/opt/reflect.h"
+#include "source/spirv_target_env.h"
+#include "source/util/string_utils.h"
+
+namespace spvtools {
+namespace opt {
+
+namespace {
+constexpr uint32_t kOpTypeFloatSizeIndex = 0;
+constexpr uint32_t kOpTypePointerStorageClassIndex = 0;
+constexpr uint32_t kTypeArrayTypeIndex = 0;
+constexpr uint32_t kOpTypeScalarBitWidthIndex = 0;
+constexpr uint32_t kTypePointerTypeIdInIndex = 1;
+constexpr uint32_t kOpTypeIntSizeIndex = 0;
+constexpr uint32_t kOpTypeImageDimIndex = 1;
+constexpr uint32_t kOpTypeImageArrayedIndex = kOpTypeImageDimIndex + 2;
+constexpr uint32_t kOpTypeImageMSIndex = kOpTypeImageArrayedIndex + 1;
+constexpr uint32_t kOpTypeImageSampledIndex = kOpTypeImageMSIndex + 1;
+constexpr uint32_t kOpTypeImageFormatIndex = kOpTypeImageSampledIndex + 1;
+constexpr uint32_t kOpImageReadImageIndex = 0;
+constexpr uint32_t kOpImageSparseReadImageIndex = 0;
+
+// DFS visit of the type defined by `instruction`.
+// If `condition` is true, children of the current node are visited.
+// If `condition` is false, the children of the current node are ignored.
+template <class UnaryPredicate>
+static void DFSWhile(const Instruction* instruction, UnaryPredicate condition) {
+ std::stack<uint32_t> instructions_to_visit;
+ instructions_to_visit.push(instruction->result_id());
+ const auto* def_use_mgr = instruction->context()->get_def_use_mgr();
+
+ while (!instructions_to_visit.empty()) {
+ const Instruction* item = def_use_mgr->GetDef(instructions_to_visit.top());
+ instructions_to_visit.pop();
+
+ if (!condition(item)) {
+ continue;
+ }
+
+ if (item->opcode() == spv::Op::OpTypePointer) {
+ instructions_to_visit.push(
+ item->GetSingleWordInOperand(kTypePointerTypeIdInIndex));
+ continue;
+ }
+
+ if (item->opcode() == spv::Op::OpTypeMatrix ||
+ item->opcode() == spv::Op::OpTypeVector ||
+ item->opcode() == spv::Op::OpTypeArray ||
+ item->opcode() == spv::Op::OpTypeRuntimeArray) {
+ instructions_to_visit.push(
+ item->GetSingleWordInOperand(kTypeArrayTypeIndex));
+ continue;
+ }
+
+ if (item->opcode() == spv::Op::OpTypeStruct) {
+ item->ForEachInOperand([&instructions_to_visit](const uint32_t* op_id) {
+ instructions_to_visit.push(*op_id);
+ });
+ continue;
+ }
+ }
+}
+
+// Walks the type defined by `instruction` (OpType* only).
+// Returns `true` if any call to `predicate` with the type/subtype returns true.
+template <class UnaryPredicate>
+static bool AnyTypeOf(const Instruction* instruction,
+ UnaryPredicate predicate) {
+ assert(IsTypeInst(instruction->opcode()) &&
+ "AnyTypeOf called with a non-type instruction.");
+
+ bool found_one = false;
+ DFSWhile(instruction, [&found_one, predicate](const Instruction* node) {
+ if (found_one || predicate(node)) {
+ found_one = true;
+ return false;
+ }
+
+ return true;
+ });
+ return found_one;
+}
+
+static bool is16bitType(const Instruction* instruction) {
+ if (instruction->opcode() != spv::Op::OpTypeInt &&
+ instruction->opcode() != spv::Op::OpTypeFloat) {
+ return false;
+ }
+
+ return instruction->GetSingleWordInOperand(kOpTypeScalarBitWidthIndex) == 16;
+}
+
+static bool Has16BitCapability(const FeatureManager* feature_manager) {
+ const CapabilitySet& capabilities = feature_manager->GetCapabilities();
+ return capabilities.contains(spv::Capability::Float16) ||
+ capabilities.contains(spv::Capability::Int16);
+}
+
+} // namespace
+
+// ============== Begin opcode handler implementations. =======================
+//
+// Adding support for a new capability should only require adding a new handler,
+// and updating the
+// kSupportedCapabilities/kUntouchableCapabilities/kFordiddenCapabilities lists.
+//
+// Handler names follow the following convention:
+// Handler_<Opcode>_<Capability>()
+
+static std::optional<spv::Capability> Handler_OpTypeFloat_Float16(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypeFloat &&
+ "This handler only support OpTypeFloat opcodes.");
+
+ const uint32_t size =
+ instruction->GetSingleWordInOperand(kOpTypeFloatSizeIndex);
+ return size == 16 ? std::optional(spv::Capability::Float16) : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypeFloat_Float64(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypeFloat &&
+ "This handler only support OpTypeFloat opcodes.");
+
+ const uint32_t size =
+ instruction->GetSingleWordInOperand(kOpTypeFloatSizeIndex);
+ return size == 64 ? std::optional(spv::Capability::Float64) : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StorageInputOutput16(const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypePointer &&
+ "This handler only support OpTypePointer opcodes.");
+
+ // This capability is only required if the variable has an Input/Output
+ // storage class.
+ spv::StorageClass storage_class = spv::StorageClass(
+ instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+ if (storage_class != spv::StorageClass::Input &&
+ storage_class != spv::StorageClass::Output) {
+ return std::nullopt;
+ }
+
+ if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+ return std::nullopt;
+ }
+
+ return AnyTypeOf(instruction, is16bitType)
+ ? std::optional(spv::Capability::StorageInputOutput16)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StoragePushConstant16(const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypePointer &&
+ "This handler only support OpTypePointer opcodes.");
+
+ // This capability is only required if the variable has a PushConstant storage
+ // class.
+ spv::StorageClass storage_class = spv::StorageClass(
+ instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+ if (storage_class != spv::StorageClass::PushConstant) {
+ return std::nullopt;
+ }
+
+ if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+ return std::nullopt;
+ }
+
+ return AnyTypeOf(instruction, is16bitType)
+ ? std::optional(spv::Capability::StoragePushConstant16)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpTypePointer_StorageUniformBufferBlock16(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypePointer &&
+ "This handler only support OpTypePointer opcodes.");
+
+ // This capability is only required if the variable has a Uniform storage
+ // class.
+ spv::StorageClass storage_class = spv::StorageClass(
+ instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+ if (storage_class != spv::StorageClass::Uniform) {
+ return std::nullopt;
+ }
+
+ if (!Has16BitCapability(instruction->context()->get_feature_mgr())) {
+ return std::nullopt;
+ }
+
+ const auto* decoration_mgr = instruction->context()->get_decoration_mgr();
+ const bool matchesCondition =
+ AnyTypeOf(instruction, [decoration_mgr](const Instruction* item) {
+ if (!decoration_mgr->HasDecoration(item->result_id(),
+ spv::Decoration::BufferBlock)) {
+ return false;
+ }
+
+ return AnyTypeOf(item, is16bitType);
+ });
+
+ return matchesCondition
+ ? std::optional(spv::Capability::StorageUniformBufferBlock16)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypePointer_StorageUniform16(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypePointer &&
+ "This handler only support OpTypePointer opcodes.");
+
+ // This capability is only required if the variable has a Uniform storage
+ // class.
+ spv::StorageClass storage_class = spv::StorageClass(
+ instruction->GetSingleWordInOperand(kOpTypePointerStorageClassIndex));
+ if (storage_class != spv::StorageClass::Uniform) {
+ return std::nullopt;
+ }
+
+ const auto* feature_manager = instruction->context()->get_feature_mgr();
+ if (!Has16BitCapability(feature_manager)) {
+ return std::nullopt;
+ }
+
+ const bool hasBufferBlockCapability =
+ feature_manager->GetCapabilities().contains(
+ spv::Capability::StorageUniformBufferBlock16);
+ const auto* decoration_mgr = instruction->context()->get_decoration_mgr();
+ bool found16bitType = false;
+
+ DFSWhile(instruction, [decoration_mgr, hasBufferBlockCapability,
+ &found16bitType](const Instruction* item) {
+ if (found16bitType) {
+ return false;
+ }
+
+ if (hasBufferBlockCapability &&
+ decoration_mgr->HasDecoration(item->result_id(),
+ spv::Decoration::BufferBlock)) {
+ return false;
+ }
+
+ if (is16bitType(item)) {
+ found16bitType = true;
+ return false;
+ }
+
+ return true;
+ });
+
+ return found16bitType ? std::optional(spv::Capability::StorageUniform16)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypeInt_Int16(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypeInt &&
+ "This handler only support OpTypeInt opcodes.");
+
+ const uint32_t size =
+ instruction->GetSingleWordInOperand(kOpTypeIntSizeIndex);
+ return size == 16 ? std::optional(spv::Capability::Int16) : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypeInt_Int64(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypeInt &&
+ "This handler only support OpTypeInt opcodes.");
+
+ const uint32_t size =
+ instruction->GetSingleWordInOperand(kOpTypeIntSizeIndex);
+ return size == 64 ? std::optional(spv::Capability::Int64) : std::nullopt;
+}
+
+static std::optional<spv::Capability> Handler_OpTypeImage_ImageMSArray(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpTypeImage &&
+ "This handler only support OpTypeImage opcodes.");
+
+ const uint32_t arrayed =
+ instruction->GetSingleWordInOperand(kOpTypeImageArrayedIndex);
+ const uint32_t ms = instruction->GetSingleWordInOperand(kOpTypeImageMSIndex);
+ const uint32_t sampled =
+ instruction->GetSingleWordInOperand(kOpTypeImageSampledIndex);
+
+ return arrayed == 1 && sampled == 2 && ms == 1
+ ? std::optional(spv::Capability::ImageMSArray)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpImageRead_StorageImageReadWithoutFormat(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpImageRead &&
+ "This handler only support OpImageRead opcodes.");
+ const auto* def_use_mgr = instruction->context()->get_def_use_mgr();
+
+ const uint32_t image_index =
+ instruction->GetSingleWordInOperand(kOpImageReadImageIndex);
+ const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id();
+ const Instruction* type = def_use_mgr->GetDef(type_index);
+ const uint32_t dim = type->GetSingleWordInOperand(kOpTypeImageDimIndex);
+ const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex);
+
+ const bool is_unknown = spv::ImageFormat(format) == spv::ImageFormat::Unknown;
+ const bool requires_capability_for_unknown =
+ spv::Dim(dim) != spv::Dim::SubpassData;
+ return is_unknown && requires_capability_for_unknown
+ ? std::optional(spv::Capability::StorageImageReadWithoutFormat)
+ : std::nullopt;
+}
+
+static std::optional<spv::Capability>
+Handler_OpImageSparseRead_StorageImageReadWithoutFormat(
+ const Instruction* instruction) {
+ assert(instruction->opcode() == spv::Op::OpImageSparseRead &&
+ "This handler only support OpImageSparseRead opcodes.");
+ const auto* def_use_mgr = instruction->context()->get_def_use_mgr();
+
+ const uint32_t image_index =
+ instruction->GetSingleWordInOperand(kOpImageSparseReadImageIndex);
+ const uint32_t type_index = def_use_mgr->GetDef(image_index)->type_id();
+ const Instruction* type = def_use_mgr->GetDef(type_index);
+ const uint32_t format = type->GetSingleWordInOperand(kOpTypeImageFormatIndex);
+
+ return spv::ImageFormat(format) == spv::ImageFormat::Unknown
+ ? std::optional(spv::Capability::StorageImageReadWithoutFormat)
+ : std::nullopt;
+}
+
+// Opcode of interest to determine capabilities requirements.
+constexpr std::array<std::pair<spv::Op, OpcodeHandler>, 12> kOpcodeHandlers{{
+ // clang-format off
+ {spv::Op::OpImageRead, Handler_OpImageRead_StorageImageReadWithoutFormat},
+ {spv::Op::OpImageSparseRead, Handler_OpImageSparseRead_StorageImageReadWithoutFormat},
+ {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float16 },
+ {spv::Op::OpTypeFloat, Handler_OpTypeFloat_Float64 },
+ {spv::Op::OpTypeImage, Handler_OpTypeImage_ImageMSArray},
+ {spv::Op::OpTypeInt, Handler_OpTypeInt_Int16 },
+ {spv::Op::OpTypeInt, Handler_OpTypeInt_Int64 },
+ {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageInputOutput16},
+ {spv::Op::OpTypePointer, Handler_OpTypePointer_StoragePushConstant16},
+ {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16},
+ {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniform16},
+ {spv::Op::OpTypePointer, Handler_OpTypePointer_StorageUniformBufferBlock16},
+ // clang-format on
+}};
+
+// ============== End opcode handler implementations. =======================
+
+namespace {
+ExtensionSet getExtensionsRelatedTo(const CapabilitySet& capabilities,
+ const AssemblyGrammar& grammar) {
+ ExtensionSet output;
+ const spv_operand_desc_t* desc = nullptr;
+ for (auto capability : capabilities) {
+ if (SPV_SUCCESS != grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
+ static_cast<uint32_t>(capability),
+ &desc)) {
+ continue;
+ }
+
+ for (uint32_t i = 0; i < desc->numExtensions; ++i) {
+ output.insert(desc->extensions[i]);
+ }
+ }
+
+ return output;
+}
+} // namespace
+
+TrimCapabilitiesPass::TrimCapabilitiesPass()
+ : supportedCapabilities_(
+ TrimCapabilitiesPass::kSupportedCapabilities.cbegin(),
+ TrimCapabilitiesPass::kSupportedCapabilities.cend()),
+ forbiddenCapabilities_(
+ TrimCapabilitiesPass::kForbiddenCapabilities.cbegin(),
+ TrimCapabilitiesPass::kForbiddenCapabilities.cend()),
+ untouchableCapabilities_(
+ TrimCapabilitiesPass::kUntouchableCapabilities.cbegin(),
+ TrimCapabilitiesPass::kUntouchableCapabilities.cend()),
+ opcodeHandlers_(kOpcodeHandlers.cbegin(), kOpcodeHandlers.cend()) {}
+
+void TrimCapabilitiesPass::addInstructionRequirementsForOpcode(
+ spv::Op opcode, CapabilitySet* capabilities,
+ ExtensionSet* extensions) const {
+ // Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT
+ // because they have three possible capabilities, only one of which is needed
+ if (opcode == spv::Op::OpBeginInvocationInterlockEXT ||
+ opcode == spv::Op::OpEndInvocationInterlockEXT) {
+ return;
+ }
+
+ const spv_opcode_desc_t* desc = {};
+ auto result = context()->grammar().lookupOpcode(opcode, &desc);
+ if (result != SPV_SUCCESS) {
+ return;
+ }
+
+ addSupportedCapabilitiesToSet(desc, capabilities);
+ addSupportedExtensionsToSet(desc, extensions);
+}
+
+void TrimCapabilitiesPass::addInstructionRequirementsForOperand(
+ const Operand& operand, CapabilitySet* capabilities,
+ ExtensionSet* extensions) const {
+ // No supported capability relies on a 2+-word operand.
+ if (operand.words.size() != 1) {
+ return;
+ }
+
+ // No supported capability relies on a literal string operand or an ID.
+ if (operand.type == SPV_OPERAND_TYPE_LITERAL_STRING ||
+ operand.type == SPV_OPERAND_TYPE_ID ||
+ operand.type == SPV_OPERAND_TYPE_RESULT_ID) {
+ return;
+ }
+
+ // If the Vulkan memory model is declared and any instruction uses Device
+ // scope, the VulkanMemoryModelDeviceScope capability must be declared. This
+ // rule cannot be covered by the grammar, so must be checked explicitly.
+ if (operand.type == SPV_OPERAND_TYPE_SCOPE_ID) {
+ const Instruction* memory_model = context()->GetMemoryModel();
+ if (memory_model && memory_model->GetSingleWordInOperand(1u) ==
+ uint32_t(spv::MemoryModel::Vulkan)) {
+ capabilities->insert(spv::Capability::VulkanMemoryModelDeviceScope);
+ }
+ }
+
+ // case 1: Operand is a single value, can directly lookup.
+ if (!spvOperandIsConcreteMask(operand.type)) {
+ const spv_operand_desc_t* desc = {};
+ auto result = context()->grammar().lookupOperand(operand.type,
+ operand.words[0], &desc);
+ if (result != SPV_SUCCESS) {
+ return;
+ }
+ addSupportedCapabilitiesToSet(desc, capabilities);
+ addSupportedExtensionsToSet(desc, extensions);
+ return;
+ }
+
+ // case 2: operand can be a bitmask, we need to decompose the lookup.
+ for (uint32_t i = 0; i < 32; i++) {
+ const uint32_t mask = (1 << i) & operand.words[0];
+ if (!mask) {
+ continue;
+ }
+
+ const spv_operand_desc_t* desc = {};
+ auto result = context()->grammar().lookupOperand(operand.type, mask, &desc);
+ if (result != SPV_SUCCESS) {
+ continue;
+ }
+
+ addSupportedCapabilitiesToSet(desc, capabilities);
+ addSupportedExtensionsToSet(desc, extensions);
+ }
+}
+
+void TrimCapabilitiesPass::addInstructionRequirements(
+ Instruction* instruction, CapabilitySet* capabilities,
+ ExtensionSet* extensions) const {
+ // Ignoring OpCapability and OpExtension instructions.
+ if (instruction->opcode() == spv::Op::OpCapability ||
+ instruction->opcode() == spv::Op::OpExtension) {
+ return;
+ }
+
+ addInstructionRequirementsForOpcode(instruction->opcode(), capabilities,
+ extensions);
+
+ // Second case: one of the opcode operand is gated by a capability.
+ const uint32_t operandCount = instruction->NumOperands();
+ for (uint32_t i = 0; i < operandCount; i++) {
+ addInstructionRequirementsForOperand(instruction->GetOperand(i),
+ capabilities, extensions);
+ }
+
+ // Last case: some complex logic needs to be run to determine capabilities.
+ auto[begin, end] = opcodeHandlers_.equal_range(instruction->opcode());
+ for (auto it = begin; it != end; it++) {
+ const OpcodeHandler handler = it->second;
+ auto result = handler(instruction);
+ if (!result.has_value()) {
+ continue;
+ }
+
+ capabilities->insert(*result);
+ }
+}
+
+void TrimCapabilitiesPass::AddExtensionsForOperand(
+ const spv_operand_type_t type, const uint32_t value,
+ ExtensionSet* extensions) const {
+ const spv_operand_desc_t* desc = nullptr;
+ spv_result_t result = context()->grammar().lookupOperand(type, value, &desc);
+ if (result != SPV_SUCCESS) {
+ return;
+ }
+ addSupportedExtensionsToSet(desc, extensions);
+}
+
+std::pair<CapabilitySet, ExtensionSet>
+TrimCapabilitiesPass::DetermineRequiredCapabilitiesAndExtensions() const {
+ CapabilitySet required_capabilities;
+ ExtensionSet required_extensions;
+
+ get_module()->ForEachInst([&](Instruction* instruction) {
+ addInstructionRequirements(instruction, &required_capabilities,
+ &required_extensions);
+ });
+
+ for (auto capability : required_capabilities) {
+ AddExtensionsForOperand(SPV_OPERAND_TYPE_CAPABILITY,
+ static_cast<uint32_t>(capability),
+ &required_extensions);
+ }
+
+#if !defined(NDEBUG)
+ // Debug only. We check the outputted required capabilities against the
+ // supported capabilities list. The supported capabilities list is useful for
+ // API users to quickly determine if they can use the pass or not. But this
+ // list has to remain up-to-date with the pass code. If we can detect a
+ // capability as required, but it's not listed, it means the list is
+ // out-of-sync. This method is not ideal, but should cover most cases.
+ {
+ for (auto capability : required_capabilities) {
+ assert(supportedCapabilities_.contains(capability) &&
+ "Module is using a capability that is not listed as supported.");
+ }
+ }
+#endif
+
+ return std::make_pair(std::move(required_capabilities),
+ std::move(required_extensions));
+}
+
+Pass::Status TrimCapabilitiesPass::TrimUnrequiredCapabilities(
+ const CapabilitySet& required_capabilities) const {
+ const FeatureManager* feature_manager = context()->get_feature_mgr();
+ CapabilitySet capabilities_to_trim;
+ for (auto capability : feature_manager->GetCapabilities()) {
+ // Some capabilities cannot be safely removed. Leaving them untouched.
+ if (untouchableCapabilities_.contains(capability)) {
+ continue;
+ }
+
+ // If the capability is unsupported, don't trim it.
+ if (!supportedCapabilities_.contains(capability)) {
+ continue;
+ }
+
+ if (required_capabilities.contains(capability)) {
+ continue;
+ }
+
+ capabilities_to_trim.insert(capability);
+ }
+
+ for (auto capability : capabilities_to_trim) {
+ context()->RemoveCapability(capability);
+ }
+
+ return capabilities_to_trim.size() == 0 ? Pass::Status::SuccessWithoutChange
+ : Pass::Status::SuccessWithChange;
+}
+
+Pass::Status TrimCapabilitiesPass::TrimUnrequiredExtensions(
+ const ExtensionSet& required_extensions) const {
+ const auto supported_extensions =
+ getExtensionsRelatedTo(supportedCapabilities_, context()->grammar());
+
+ bool modified_module = false;
+ for (auto extension : supported_extensions) {
+ if (required_extensions.contains(extension)) {
+ continue;
+ }
+
+ if (context()->RemoveExtension(extension)) {
+ modified_module = true;
+ }
+ }
+
+ return modified_module ? Pass::Status::SuccessWithChange
+ : Pass::Status::SuccessWithoutChange;
+}
+
+bool TrimCapabilitiesPass::HasForbiddenCapabilities() const {
+ // EnumSet.HasAnyOf returns `true` if the given set is empty.
+ if (forbiddenCapabilities_.size() == 0) {
+ return false;
+ }
+
+ const auto& capabilities = context()->get_feature_mgr()->GetCapabilities();
+ return capabilities.HasAnyOf(forbiddenCapabilities_);
+}
+
+Pass::Status TrimCapabilitiesPass::Process() {
+ if (HasForbiddenCapabilities()) {
+ return Status::SuccessWithoutChange;
+ }
+
+ auto[required_capabilities, required_extensions] =
+ DetermineRequiredCapabilitiesAndExtensions();
+
+ Pass::Status capStatus = TrimUnrequiredCapabilities(required_capabilities);
+ Pass::Status extStatus = TrimUnrequiredExtensions(required_extensions);
+
+ return capStatus == Pass::Status::SuccessWithChange ||
+ extStatus == Pass::Status::SuccessWithChange
+ ? Pass::Status::SuccessWithChange
+ : Pass::Status::SuccessWithoutChange;
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.h b/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.h
new file mode 100644
index 000000000..81c07b822
--- /dev/null
+++ b/third_party/SPIRV-Tools/source/opt/trim_capabilities_pass.h
@@ -0,0 +1,205 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_
+#define SOURCE_OPT_TRIM_CAPABILITIES_PASS_H_
+
+#include <algorithm>
+#include <array>
+#include <functional>
+#include <optional>
+#include <unordered_map>
+#include <unordered_set>
+
+#include "source/enum_set.h"
+#include "source/extensions.h"
+#include "source/opt/ir_context.h"
+#include "source/opt/module.h"
+#include "source/opt/pass.h"
+#include "source/spirv_target_env.h"
+
+namespace spvtools {
+namespace opt {
+
+// This is required for NDK build. The unordered_set/unordered_map
+// implementation don't work with class enums.
+struct ClassEnumHash {
+ std::size_t operator()(spv::Capability value) const {
+ using StoringType = typename std::underlying_type_t<spv::Capability>;
+ return std::hash<StoringType>{}(static_cast<StoringType>(value));
+ }
+
+ std::size_t operator()(spv::Op value) const {
+ using StoringType = typename std::underlying_type_t<spv::Op>;
+ return std::hash<StoringType>{}(static_cast<StoringType>(value));
+ }
+};
+
+// An opcode handler is a function which, given an instruction, returns either
+// the required capability, or nothing.
+// Each handler checks one case for a capability requirement.
+//
+// Example:
+// - `OpTypeImage` can have operand `A` operand which requires capability 1
+// - `OpTypeImage` can also have operand `B` which requires capability 2.
+// -> We have 2 handlers: `Handler_OpTypeImage_1` and
+// `Handler_OpTypeImage_2`.
+using OpcodeHandler =
+ std::optional<spv::Capability> (*)(const Instruction* instruction);
+
+// This pass tried to remove superfluous capabilities declared in the module.
+// - If all the capabilities listed by an extension are removed, the extension
+// is also trimmed.
+// - If the module countains any capability listed in `kForbiddenCapabilities`,
+// the module is left untouched.
+// - No capabilities listed in `kUntouchableCapabilities` are trimmed, even when
+// not used.
+// - Only capabilitied listed in `kSupportedCapabilities` are supported.
+// - If the module contains unsupported capabilities, results might be
+// incorrect.
+class TrimCapabilitiesPass : public Pass {
+ private:
+ // All the capabilities supported by this optimization pass. If your module
+ // contains unsupported instruction, the pass could yield bad results.
+ static constexpr std::array kSupportedCapabilities{
+ // clang-format off
+ spv::Capability::ComputeDerivativeGroupLinearNV,
+ spv::Capability::ComputeDerivativeGroupQuadsNV,
+ spv::Capability::Float16,
+ spv::Capability::Float64,
+ spv::Capability::FragmentShaderPixelInterlockEXT,
+ spv::Capability::FragmentShaderSampleInterlockEXT,
+ spv::Capability::FragmentShaderShadingRateInterlockEXT,
+ spv::Capability::Groups,
+ spv::Capability::ImageMSArray,
+ spv::Capability::Int16,
+ spv::Capability::Int64,
+ spv::Capability::Linkage,
+ spv::Capability::MinLod,
+ spv::Capability::PhysicalStorageBufferAddresses,
+ spv::Capability::RayQueryKHR,
+ spv::Capability::RayTracingKHR,
+ spv::Capability::RayTraversalPrimitiveCullingKHR,
+ spv::Capability::Shader,
+ spv::Capability::ShaderClockKHR,
+ spv::Capability::StorageImageReadWithoutFormat,
+ spv::Capability::StorageInputOutput16,
+ spv::Capability::StoragePushConstant16,
+ spv::Capability::StorageUniform16,
+ spv::Capability::StorageUniformBufferBlock16,
+ spv::Capability::VulkanMemoryModelDeviceScope,
+ spv::Capability::GroupNonUniformPartitionedNV
+ // clang-format on
+ };
+
+ // Those capabilities disable all transformation of the module.
+ static constexpr std::array kForbiddenCapabilities{
+ spv::Capability::Linkage,
+ };
+
+ // Those capabilities are never removed from a module because we cannot
+ // guess from the SPIR-V only if they are required or not.
+ static constexpr std::array kUntouchableCapabilities{
+ spv::Capability::Shader,
+ };
+
+ public:
+ TrimCapabilitiesPass();
+ TrimCapabilitiesPass(const TrimCapabilitiesPass&) = delete;
+ TrimCapabilitiesPass(TrimCapabilitiesPass&&) = delete;
+
+ private:
+ // Inserts every capability listed by `descriptor` this pass supports into
+ // `output`. Expects a Descriptor like `spv_opcode_desc_t` or
+ // `spv_operand_desc_t`.
+ template <class Descriptor>
+ inline void addSupportedCapabilitiesToSet(const Descriptor* const descriptor,
+ CapabilitySet* output) const {
+ const uint32_t capabilityCount = descriptor->numCapabilities;
+ for (uint32_t i = 0; i < capabilityCount; ++i) {
+ const auto capability = descriptor->capabilities[i];
+ if (supportedCapabilities_.contains(capability)) {
+ output->insert(capability);
+ }
+ }
+ }
+
+ // Inserts every extension listed by `descriptor` required by the module into
+ // `output`. Expects a Descriptor like `spv_opcode_desc_t` or
+ // `spv_operand_desc_t`.
+ template <class Descriptor>
+ inline void addSupportedExtensionsToSet(const Descriptor* const descriptor,
+ ExtensionSet* output) const {
+ if (descriptor->minVersion <=
+ spvVersionForTargetEnv(context()->GetTargetEnv())) {
+ return;
+ }
+ output->insert(descriptor->extensions,
+ descriptor->extensions + descriptor->numExtensions);
+ }
+
+ void addInstructionRequirementsForOpcode(spv::Op opcode,
+ CapabilitySet* capabilities,
+ ExtensionSet* extensions) const;
+ void addInstructionRequirementsForOperand(const Operand& operand,
+ CapabilitySet* capabilities,
+ ExtensionSet* extensions) const;
+
+ // Given an `instruction`, determines the capabilities it requires, and output
+ // them in `capabilities`. The returned capabilities form a subset of
+ // kSupportedCapabilities.
+ void addInstructionRequirements(Instruction* instruction,
+ CapabilitySet* capabilities,
+ ExtensionSet* extensions) const;
+
+ // Given an operand `type` and `value`, adds the extensions it would require
+ // to `extensions`.
+ void AddExtensionsForOperand(const spv_operand_type_t type,
+ const uint32_t value,
+ ExtensionSet* extensions) const;
+
+ // Returns the list of required capabilities and extensions for the module.
+ // The returned capabilities form a subset of kSupportedCapabilities.
+ std::pair<CapabilitySet, ExtensionSet>
+ DetermineRequiredCapabilitiesAndExtensions() const;
+
+ // Trims capabilities not listed in `required_capabilities` if possible.
+ // Returns whether or not the module was modified.
+ Pass::Status TrimUnrequiredCapabilities(
+ const CapabilitySet& required_capabilities) const;
+
+ // Trims extensions not listed in `required_extensions` if supported by this
+ // pass. An extensions is considered supported as soon as one capability this
+ // pass support requires it.
+ Pass::Status TrimUnrequiredExtensions(
+ const ExtensionSet& required_extensions) const;
+
+ // Returns if the analyzed module contains any forbidden capability.
+ bool HasForbiddenCapabilities() const;
+
+ public:
+ const char* name() const override { return "trim-capabilities"; }
+ Status Process() override;
+
+ private:
+ const CapabilitySet supportedCapabilities_;
+ const CapabilitySet forbiddenCapabilities_;
+ const CapabilitySet untouchableCapabilities_;
+ const std::unordered_multimap<spv::Op, OpcodeHandler, ClassEnumHash>
+ opcodeHandlers_;
+};
+
+} // namespace opt
+} // namespace spvtools
+#endif // SOURCE_OPT_TRIM_CAPABILITIES_H_
diff --git a/third_party/SPIRV-Tools/source/opt/type_manager.cpp b/third_party/SPIRV-Tools/source/opt/type_manager.cpp
index 1b1aeadc8..7b609bc77 100644
--- a/third_party/SPIRV-Tools/source/opt/type_manager.cpp
+++ b/third_party/SPIRV-Tools/source/opt/type_manager.cpp
@@ -423,6 +423,23 @@ uint32_t TypeManager::GetTypeInstruction(const Type* type) {
{SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}}});
break;
}
+ case Type::kCooperativeMatrixKHR: {
+ auto coop_mat = type->AsCooperativeMatrixKHR();
+ uint32_t const component_type =
+ GetTypeInstruction(coop_mat->component_type());
+ if (component_type == 0) {
+ return 0;
+ }
+ typeInst = MakeUnique<Instruction>(
+ context(), spv::Op::OpTypeCooperativeMatrixKHR, 0, id,
+ std::initializer_list<Operand>{
+ {SPV_OPERAND_TYPE_ID, {component_type}},
+ {SPV_OPERAND_TYPE_SCOPE_ID, {coop_mat->scope_id()}},
+ {SPV_OPERAND_TYPE_ID, {coop_mat->rows_id()}},
+ {SPV_OPERAND_TYPE_ID, {coop_mat->columns_id()}},
+ {SPV_OPERAND_TYPE_ID, {coop_mat->use_id()}}});
+ break;
+ }
default:
assert(false && "Unexpected type");
break;
@@ -500,13 +517,24 @@ void TypeManager::CreateDecoration(uint32_t target,
context()->get_def_use_mgr()->AnalyzeInstUse(inst);
}
-Type* TypeManager::RebuildType(const Type& type) {
+Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) {
+ assert(type_id != 0);
+
// The comparison and hash on the type pool will avoid inserting the rebuilt
// type if an equivalent type already exists. The rebuilt type will be deleted
// when it goes out of scope at the end of the function in that case. Repeated
// insertions of the same Type will, at most, keep one corresponding object in
// the type pool.
std::unique_ptr<Type> rebuilt_ty;
+
+ // If |type_id| is already present in the type pool, return the existing type.
+ // This saves extra work in the type builder and prevents running into
+ // circular issues (https://github.com/KhronosGroup/SPIRV-Tools/issues/5623).
+ Type* pool_ty = GetType(type_id);
+ if (pool_ty != nullptr) {
+ return pool_ty;
+ }
+
switch (type.kind()) {
#define DefineNoSubtypeCase(kind) \
case Type::k##kind: \
@@ -533,43 +561,46 @@ Type* TypeManager::RebuildType(const Type& type) {
case Type::kVector: {
const Vector* vec_ty = type.AsVector();
const Type* ele_ty = vec_ty->element_type();
- rebuilt_ty =
- MakeUnique<Vector>(RebuildType(*ele_ty), vec_ty->element_count());
+ rebuilt_ty = MakeUnique<Vector>(RebuildType(GetId(ele_ty), *ele_ty),
+ vec_ty->element_count());
break;
}
case Type::kMatrix: {
const Matrix* mat_ty = type.AsMatrix();
const Type* ele_ty = mat_ty->element_type();
- rebuilt_ty =
- MakeUnique<Matrix>(RebuildType(*ele_ty), mat_ty->element_count());
+ rebuilt_ty = MakeUnique<Matrix>(RebuildType(GetId(ele_ty), *ele_ty),
+ mat_ty->element_count());
break;
}
case Type::kImage: {
const Image* image_ty = type.AsImage();
const Type* ele_ty = image_ty->sampled_type();
- rebuilt_ty =
- MakeUnique<Image>(RebuildType(*ele_ty), image_ty->dim(),
- image_ty->depth(), image_ty->is_arrayed(),
- image_ty->is_multisampled(), image_ty->sampled(),
- image_ty->format(), image_ty->access_qualifier());
+ rebuilt_ty = MakeUnique<Image>(
+ RebuildType(GetId(ele_ty), *ele_ty), image_ty->dim(),
+ image_ty->depth(), image_ty->is_arrayed(),
+ image_ty->is_multisampled(), image_ty->sampled(), image_ty->format(),
+ image_ty->access_qualifier());
break;
}
case Type::kSampledImage: {
const SampledImage* image_ty = type.AsSampledImage();
const Type* ele_ty = image_ty->image_type();
- rebuilt_ty = MakeUnique<SampledImage>(RebuildType(*ele_ty));
+ rebuilt_ty =
+ MakeUnique<SampledImage>(RebuildType(GetId(ele_ty), *ele_ty));
break;
}
case Type::kArray: {
const Array* array_ty = type.AsArray();
- rebuilt_ty =
- MakeUnique<Array>(array_ty->element_type(), array_ty->length_info());
+ const Type* ele_ty = array_ty->element_type();
+ rebuilt_ty = MakeUnique<Array>(RebuildType(GetId(ele_ty), *ele_ty),
+ array_ty->length_info());
break;
}
case Type::kRuntimeArray: {
const RuntimeArray* array_ty = type.AsRuntimeArray();
const Type* ele_ty = array_ty->element_type();
- rebuilt_ty = MakeUnique<RuntimeArray>(RebuildType(*ele_ty));
+ rebuilt_ty =
+ MakeUnique<RuntimeArray>(RebuildType(GetId(ele_ty), *ele_ty));
break;
}
case Type::kStruct: {
@@ -577,7 +608,7 @@ Type* TypeManager::RebuildType(const Type& type) {
std::vector<const Type*> subtypes;
subtypes.reserve(struct_ty->element_types().size());
for (const auto* ele_ty : struct_ty->element_types()) {
- subtypes.push_back(RebuildType(*ele_ty));
+ subtypes.push_back(RebuildType(GetId(ele_ty), *ele_ty));
}
rebuilt_ty = MakeUnique<Struct>(subtypes);
Struct* rebuilt_struct = rebuilt_ty->AsStruct();
@@ -594,7 +625,7 @@ Type* TypeManager::RebuildType(const Type& type) {
case Type::kPointer: {
const Pointer* pointer_ty = type.AsPointer();
const Type* ele_ty = pointer_ty->pointee_type();
- rebuilt_ty = MakeUnique<Pointer>(RebuildType(*ele_ty),
+ rebuilt_ty = MakeUnique<Pointer>(RebuildType(GetId(ele_ty), *ele_ty),
pointer_ty->storage_class());
break;
}
@@ -604,9 +635,10 @@ Type* TypeManager::RebuildType(const Type& type) {
std::vector<const Type*> param_types;
param_types.reserve(function_ty->param_types().size());
for (const auto* param_ty : function_ty->param_types()) {
- param_types.push_back(RebuildType(*param_ty));
+ param_types.push_back(RebuildType(GetId(param_ty), *param_ty));
}
- rebuilt_ty = MakeUnique<Function>(RebuildType(*ret_ty), param_types);
+ rebuilt_ty = MakeUnique<Function>(RebuildType(GetId(ret_ty), *ret_ty),
+ param_types);
break;
}
case Type::kForwardPointer: {
@@ -616,7 +648,7 @@ Type* TypeManager::RebuildType(const Type& type) {
const Pointer* target_ptr = forward_ptr_ty->target_pointer();
if (target_ptr) {
rebuilt_ty->AsForwardPointer()->SetTargetPointer(
- RebuildType(*target_ptr)->AsPointer());
+ RebuildType(GetId(target_ptr), *target_ptr)->AsPointer());
}
break;
}
@@ -624,8 +656,17 @@ Type* TypeManager::RebuildType(const Type& type) {
const CooperativeMatrixNV* cm_type = type.AsCooperativeMatrixNV();
const Type* component_type = cm_type->component_type();
rebuilt_ty = MakeUnique<CooperativeMatrixNV>(
- RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(),
- cm_type->columns_id());
+ RebuildType(GetId(component_type), *component_type),
+ cm_type->scope_id(), cm_type->rows_id(), cm_type->columns_id());
+ break;
+ }
+ case Type::kCooperativeMatrixKHR: {
+ const CooperativeMatrixKHR* cm_type = type.AsCooperativeMatrixKHR();
+ const Type* component_type = cm_type->component_type();
+ rebuilt_ty = MakeUnique<CooperativeMatrixKHR>(
+ RebuildType(GetId(component_type), *component_type),
+ cm_type->scope_id(), cm_type->rows_id(), cm_type->columns_id(),
+ cm_type->use_id());
break;
}
default:
@@ -644,7 +685,7 @@ Type* TypeManager::RebuildType(const Type& type) {
void TypeManager::RegisterType(uint32_t id, const Type& type) {
// Rebuild |type| so it and all its constituent types are owned by the type
// pool.
- Type* rebuilt = RebuildType(type);
+ Type* rebuilt = RebuildType(id, type);
assert(rebuilt->IsSame(&type));
id_to_type_[id] = rebuilt;
if (GetId(rebuilt) == 0) {
@@ -863,6 +904,12 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) {
inst.GetSingleWordInOperand(2),
inst.GetSingleWordInOperand(3));
break;
+ case spv::Op::OpTypeCooperativeMatrixKHR:
+ type = new CooperativeMatrixKHR(
+ GetType(inst.GetSingleWordInOperand(0)),
+ inst.GetSingleWordInOperand(1), inst.GetSingleWordInOperand(2),
+ inst.GetSingleWordInOperand(3), inst.GetSingleWordInOperand(4));
+ break;
case spv::Op::OpTypeRayQueryKHR:
type = new RayQueryKHR();
break;
@@ -870,7 +917,7 @@ Type* TypeManager::RecordIfTypeDefinition(const Instruction& inst) {
type = new HitObjectNV();
break;
default:
- SPIRV_UNIMPLEMENTED(consumer_, "unhandled type");
+ assert(false && "Type not handled by the type manager.");
break;
}
@@ -912,12 +959,10 @@ void TypeManager::AttachDecoration(const Instruction& inst, Type* type) {
}
if (Struct* st = type->AsStruct()) {
st->AddMemberDecoration(index, std::move(data));
- } else {
- SPIRV_UNIMPLEMENTED(consumer_, "OpMemberDecorate non-struct type");
}
} break;
default:
- SPIRV_UNREACHABLE(consumer_);
+ assert(false && "Unexpected opcode for a decoration instruction.");
break;
}
}
diff --git a/third_party/SPIRV-Tools/source/opt/type_manager.h b/third_party/SPIRV-Tools/source/opt/type_manager.h
index c49e19322..948b691ba 100644
--- a/third_party/SPIRV-Tools/source/opt/type_manager.h
+++ b/third_party/SPIRV-Tools/source/opt/type_manager.h
@@ -144,18 +144,17 @@ class TypeManager {
// |type| (e.g. should be called in loop of |type|'s decorations).
void AttachDecoration(const Instruction& inst, Type* type);
- Type* GetUIntType() {
- Integer int_type(32, false);
- return GetRegisteredType(&int_type);
- }
+ Type* GetUIntType() { return GetIntType(32, false); }
uint32_t GetUIntTypeId() { return GetTypeInstruction(GetUIntType()); }
- Type* GetSIntType() {
- Integer int_type(32, true);
+ Type* GetIntType(int32_t bitWidth, bool isSigned) {
+ Integer int_type(bitWidth, isSigned);
return GetRegisteredType(&int_type);
}
+ Type* GetSIntType() { return GetIntType(32, true); }
+
uint32_t GetSIntTypeId() { return GetTypeInstruction(GetSIntType()); }
Type* GetFloatType() {
@@ -261,7 +260,9 @@ class TypeManager {
// Returns an equivalent pointer to |type| built in terms of pointers owned by
// |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt
// replacing the bool subtype with one owned by |type_pool_|.
- Type* RebuildType(const Type& type);
+ //
+ // The re-built type will have ID |type_id|.
+ Type* RebuildType(uint32_t type_id, const Type& type);
// Completes the incomplete type |type|, by replaces all references to
// ForwardPointer by the defining Pointer.
diff --git a/third_party/SPIRV-Tools/source/opt/types.cpp b/third_party/SPIRV-Tools/source/opt/types.cpp
index 49eec9b74..b18b8cb1a 100644
--- a/third_party/SPIRV-Tools/source/opt/types.cpp
+++ b/third_party/SPIRV-Tools/source/opt/types.cpp
@@ -128,6 +128,7 @@ std::unique_ptr<Type> Type::Clone() const {
DeclareKindCase(NamedBarrier);
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
+ DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
#undef DeclareKindCase
@@ -175,6 +176,7 @@ bool Type::operator==(const Type& other) const {
DeclareKindCase(NamedBarrier);
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
+ DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
#undef DeclareKindCase
@@ -230,6 +232,7 @@ size_t Type::ComputeHashValue(size_t hash, SeenTypes* seen) const {
DeclareKindCase(NamedBarrier);
DeclareKindCase(AccelerationStructureNV);
DeclareKindCase(CooperativeMatrixNV);
+ DeclareKindCase(CooperativeMatrixKHR);
DeclareKindCase(RayQueryKHR);
DeclareKindCase(HitObjectNV);
#undef DeclareKindCase
@@ -708,6 +711,45 @@ bool CooperativeMatrixNV::IsSameImpl(const Type* that,
columns_id_ == mt->columns_id_ && HasSameDecorations(that);
}
+CooperativeMatrixKHR::CooperativeMatrixKHR(const Type* type,
+ const uint32_t scope,
+ const uint32_t rows,
+ const uint32_t columns,
+ const uint32_t use)
+ : Type(kCooperativeMatrixKHR),
+ component_type_(type),
+ scope_id_(scope),
+ rows_id_(rows),
+ columns_id_(columns),
+ use_id_(use) {
+ assert(type != nullptr);
+ assert(scope != 0);
+ assert(rows != 0);
+ assert(columns != 0);
+}
+
+std::string CooperativeMatrixKHR::str() const {
+ std::ostringstream oss;
+ oss << "<" << component_type_->str() << ", " << scope_id_ << ", " << rows_id_
+ << ", " << columns_id_ << ", " << use_id_ << ">";
+ return oss.str();
+}
+
+size_t CooperativeMatrixKHR::ComputeExtraStateHash(size_t hash,
+ SeenTypes* seen) const {
+ hash = hash_combine(hash, scope_id_, rows_id_, columns_id_, use_id_);
+ return component_type_->ComputeHashValue(hash, seen);
+}
+
+bool CooperativeMatrixKHR::IsSameImpl(const Type* that,
+ IsSameCache* seen) const {
+ const CooperativeMatrixKHR* mt = that->AsCooperativeMatrixKHR();
+ if (!mt) return false;
+ return component_type_->IsSameImpl(mt->component_type_, seen) &&
+ scope_id_ == mt->scope_id_ && rows_id_ == mt->rows_id_ &&
+ columns_id_ == mt->columns_id_ && HasSameDecorations(that);
+}
+
} // namespace analysis
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/opt/types.h b/third_party/SPIRV-Tools/source/opt/types.h
index 26c058c6f..16a948cec 100644
--- a/third_party/SPIRV-Tools/source/opt/types.h
+++ b/third_party/SPIRV-Tools/source/opt/types.h
@@ -60,6 +60,7 @@ class PipeStorage;
class NamedBarrier;
class AccelerationStructureNV;
class CooperativeMatrixNV;
+class CooperativeMatrixKHR;
class RayQueryKHR;
class HitObjectNV;
@@ -100,6 +101,7 @@ class Type {
kNamedBarrier,
kAccelerationStructureNV,
kCooperativeMatrixNV,
+ kCooperativeMatrixKHR,
kRayQueryKHR,
kHitObjectNV,
kLast
@@ -201,6 +203,7 @@ class Type {
DeclareCastMethod(NamedBarrier)
DeclareCastMethod(AccelerationStructureNV)
DeclareCastMethod(CooperativeMatrixNV)
+ DeclareCastMethod(CooperativeMatrixKHR)
DeclareCastMethod(RayQueryKHR)
DeclareCastMethod(HitObjectNV)
#undef DeclareCastMethod
@@ -624,6 +627,38 @@ class CooperativeMatrixNV : public Type {
const uint32_t columns_id_;
};
+class CooperativeMatrixKHR : public Type {
+ public:
+ CooperativeMatrixKHR(const Type* type, const uint32_t scope,
+ const uint32_t rows, const uint32_t columns,
+ const uint32_t use);
+ CooperativeMatrixKHR(const CooperativeMatrixKHR&) = default;
+
+ std::string str() const override;
+
+ CooperativeMatrixKHR* AsCooperativeMatrixKHR() override { return this; }
+ const CooperativeMatrixKHR* AsCooperativeMatrixKHR() const override {
+ return this;
+ }
+
+ size_t ComputeExtraStateHash(size_t hash, SeenTypes* seen) const override;
+
+ const Type* component_type() const { return component_type_; }
+ uint32_t scope_id() const { return scope_id_; }
+ uint32_t rows_id() const { return rows_id_; }
+ uint32_t columns_id() const { return columns_id_; }
+ uint32_t use_id() const { return use_id_; }
+
+ private:
+ bool IsSameImpl(const Type* that, IsSameCache*) const override;
+
+ const Type* component_type_;
+ const uint32_t scope_id_;
+ const uint32_t rows_id_;
+ const uint32_t columns_id_;
+ const uint32_t use_id_;
+};
+
#define DefineParameterlessType(type, name) \
class type : public Type { \
public: \
diff --git a/third_party/SPIRV-Tools/source/parsed_operand.cpp b/third_party/SPIRV-Tools/source/parsed_operand.cpp
index 5f8e94db8..cc33f8ba2 100644
--- a/third_party/SPIRV-Tools/source/parsed_operand.cpp
+++ b/third_party/SPIRV-Tools/source/parsed_operand.cpp
@@ -24,6 +24,7 @@ namespace spvtools {
void EmitNumericLiteral(std::ostream* out, const spv_parsed_instruction_t& inst,
const spv_parsed_operand_t& operand) {
if (operand.type != SPV_OPERAND_TYPE_LITERAL_INTEGER &&
+ operand.type != SPV_OPERAND_TYPE_LITERAL_FLOAT &&
operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER &&
operand.type != SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER &&
operand.type != SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER)
diff --git a/third_party/SPIRV-Tools/source/print.cpp b/third_party/SPIRV-Tools/source/print.cpp
index 6c94e2b7f..f36812ef5 100644
--- a/third_party/SPIRV-Tools/source/print.cpp
+++ b/third_party/SPIRV-Tools/source/print.cpp
@@ -17,7 +17,7 @@
#if defined(SPIRV_ANDROID) || defined(SPIRV_LINUX) || defined(SPIRV_MAC) || \
defined(SPIRV_IOS) || defined(SPIRV_TVOS) || defined(SPIRV_FREEBSD) || \
defined(SPIRV_OPENBSD) || defined(SPIRV_EMSCRIPTEN) || \
- defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU)
+ defined(SPIRV_FUCHSIA) || defined(SPIRV_GNU) || defined(SPIRV_QNX)
namespace spvtools {
clr::reset::operator const char*() { return "\x1b[0m"; }
diff --git a/third_party/SPIRV-Tools/source/table.h b/third_party/SPIRV-Tools/source/table.h
index 8097f13f7..4f1dc1f84 100644
--- a/third_party/SPIRV-Tools/source/table.h
+++ b/third_party/SPIRV-Tools/source/table.h
@@ -74,7 +74,7 @@ typedef struct spv_ext_inst_desc_t {
const uint32_t ext_inst;
const uint32_t numCapabilities;
const spv::Capability* capabilities;
- const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger?
+ const spv_operand_type_t operandTypes[40]; // vksp needs at least 40
} spv_ext_inst_desc_t;
typedef struct spv_ext_inst_group_t {
diff --git a/third_party/SPIRV-Tools/source/text.cpp b/third_party/SPIRV-Tools/source/text.cpp
index 8f77d624a..263bacd7b 100644
--- a/third_party/SPIRV-Tools/source/text.cpp
+++ b/third_party/SPIRV-Tools/source/text.cpp
@@ -312,6 +312,17 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar,
}
} break;
+ case SPV_OPERAND_TYPE_LITERAL_FLOAT: {
+ // The current operand is a 32-bit float.
+ // That's just how the grammar works.
+ spvtools::IdType expected_type = {
+ 32, false, spvtools::IdTypeClass::kScalarFloatType};
+ if (auto error = context->binaryEncodeNumericLiteral(
+ textValue, error_code_for_literals, expected_type, pInst)) {
+ return error;
+ }
+ } break;
+
case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
// This is a context-independent literal number which can be a 32-bit
// number of floating point value.
@@ -400,9 +411,11 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar,
case SPV_OPERAND_TYPE_IMAGE:
case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
+ case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS:
case SPV_OPERAND_TYPE_SELECTION_CONTROL:
case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
- case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: {
+ case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
+ case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: {
uint32_t value;
if (auto error = grammar.parseMaskOperand(type, textValue, &value)) {
return context->diagnostic(error)
@@ -544,7 +557,8 @@ spv_result_t spvTextEncodeOpcode(const spvtools::AssemblyGrammar& grammar,
std::string equal_sign;
error = context->getWord(&equal_sign, &nextPosition);
if ("=" != equal_sign)
- return context->diagnostic() << "'=' expected after result id.";
+ return context->diagnostic() << "'=' expected after result id but found '"
+ << equal_sign << "'.";
// The <opcode> after the '=' sign.
context->setPosition(nextPosition);
diff --git a/third_party/SPIRV-Tools/source/val/validate.cpp b/third_party/SPIRV-Tools/source/val/validate.cpp
index e73e46602..32368075c 100644
--- a/third_party/SPIRV-Tools/source/val/validate.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate.cpp
@@ -141,6 +141,13 @@ spv_result_t ValidateEntryPoints(ValidationState_t& _) {
}
}
+ if (auto error = ValidateFloatControls2(_)) {
+ return error;
+ }
+ if (auto error = ValidateDuplicateExecutionModes(_)) {
+ return error;
+ }
+
return SPV_SUCCESS;
}
@@ -381,6 +388,8 @@ spv_result_t ValidateBinaryUsingContextAndValidationState(
for (const auto& inst : vstate->ordered_instructions()) {
if (auto error = ValidateExecutionLimitations(*vstate, &inst)) return error;
if (auto error = ValidateSmallTypeUses(*vstate, &inst)) return error;
+ if (auto error = ValidateQCOMImageProcessingTextureUsages(*vstate, &inst))
+ return error;
}
return SPV_SUCCESS;
diff --git a/third_party/SPIRV-Tools/source/val/validate.h b/third_party/SPIRV-Tools/source/val/validate.h
index 2cd229f96..78093ce5f 100644
--- a/third_party/SPIRV-Tools/source/val/validate.h
+++ b/third_party/SPIRV-Tools/source/val/validate.h
@@ -82,6 +82,25 @@ spv_result_t ValidateAdjacency(ValidationState_t& _);
/// @return SPV_SUCCESS if no errors are found.
spv_result_t ValidateInterfaces(ValidationState_t& _);
+/// @brief Validates entry point call tree requirements of
+/// SPV_KHR_float_controls2
+///
+/// Checks that no entry point using FPFastMathDefault uses:
+/// * FPFastMathMode Fast
+/// * NoContraction
+///
+/// @param[in] _ the validation state of the module
+///
+/// @return SPV_SUCCESS if no errors are found.
+spv_result_t ValidateFloatControls2(ValidationState_t& _);
+
+/// @brief Validates duplicated execution modes for each entry point.
+///
+/// @param[in] _ the validation state of the module
+///
+/// @return SPV_SUCCESS if no errors are found.
+spv_result_t ValidateDuplicateExecutionModes(ValidationState_t& _);
+
/// @brief Validates memory instructions
///
/// @param[in] _ the validation state of the module
@@ -220,6 +239,14 @@ spv_result_t ValidateExecutionLimitations(ValidationState_t& _,
spv_result_t ValidateSmallTypeUses(ValidationState_t& _,
const Instruction* inst);
+/// Validates restricted uses of QCOM decorated textures
+///
+/// The textures that are decorated with some of QCOM image processing
+/// decorations must be used in the specified QCOM image processing built-in
+/// functions and not used in any other image functions.
+spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
+ const Instruction* inst);
+
/// @brief Validate the ID's within a SPIR-V binary
///
/// @param[in] pInstructions array of instructions
diff --git a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
index 73d0285a1..dac358578 100644
--- a/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_annotation.cpp
@@ -161,7 +161,8 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec,
case spv::Decoration::RestrictPointer:
case spv::Decoration::AliasedPointer:
if (target->opcode() != spv::Op::OpVariable &&
- target->opcode() != spv::Op::OpFunctionParameter) {
+ target->opcode() != spv::Op::OpFunctionParameter &&
+ target->opcode() != spv::Op::OpRawAccessChainNV) {
return fail(0) << "must be a memory object declaration";
}
if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) {
@@ -267,6 +268,34 @@ spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) {
}
}
+ if (decoration == spv::Decoration::FPFastMathMode) {
+ if (_.HasDecoration(target_id, spv::Decoration::NoContraction)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "FPFastMathMode and NoContraction cannot decorate the same "
+ "target";
+ }
+ auto mask = inst->GetOperandAs<spv::FPFastMathModeMask>(2);
+ if ((mask & spv::FPFastMathModeMask::AllowTransform) !=
+ spv::FPFastMathModeMask::MaskNone &&
+ ((mask & (spv::FPFastMathModeMask::AllowContract |
+ spv::FPFastMathModeMask::AllowReassoc)) !=
+ (spv::FPFastMathModeMask::AllowContract |
+ spv::FPFastMathModeMask::AllowReassoc))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "AllowReassoc and AllowContract must be specified when "
+ "AllowTransform is specified";
+ }
+ }
+
+ // This is checked from both sides since we register decorations as we go.
+ if (decoration == spv::Decoration::NoContraction) {
+ if (_.HasDecoration(target_id, spv::Decoration::FPFastMathMode)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "FPFastMathMode and NoContraction cannot decorate the same "
+ "target";
+ }
+ }
+
if (DecorationTakesIdParameters(decoration)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Decorations taking ID parameters may not be used with "
diff --git a/third_party/SPIRV-Tools/source/val/validate_arithmetics.cpp b/third_party/SPIRV-Tools/source/val/validate_arithmetics.cpp
index 4e7dd5e88..b608a8595 100644
--- a/third_party/SPIRV-Tools/source/val/validate_arithmetics.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_arithmetics.cpp
@@ -42,14 +42,29 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
opcode != spv::Op::OpFMod);
if (!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type) &&
- !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)))
+ !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)) &&
+ !(opcode == spv::Op::OpFMul &&
+ _.IsCooperativeMatrixKHRType(result_type) &&
+ _.IsFloatCooperativeMatrixType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected floating scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- if (_.GetOperandTypeId(inst, operand_index) != result_type)
+ if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
+ const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
+ if (!_.IsCooperativeMatrixKHRType(type_id) ||
+ !_.IsFloatCooperativeMatrixType(type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected arithmetic operands to be of Result Type: "
+ << spvOpcodeString(opcode) << " operand index "
+ << operand_index;
+ }
+ spv_result_t ret =
+ _.CooperativeMatrixShapesMatch(inst, type_id, result_type);
+ if (ret != SPV_SUCCESS) return ret;
+ } else if (_.GetOperandTypeId(inst, operand_index) != result_type)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
@@ -71,7 +86,19 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
- if (_.GetOperandTypeId(inst, operand_index) != result_type)
+ if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
+ const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
+ if (!_.IsCooperativeMatrixKHRType(type_id) ||
+ !_.IsUnsignedIntCooperativeMatrixType(type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected arithmetic operands to be of Result Type: "
+ << spvOpcodeString(opcode) << " operand index "
+ << operand_index;
+ }
+ spv_result_t ret =
+ _.CooperativeMatrixShapesMatch(inst, type_id, result_type);
+ if (ret != SPV_SUCCESS) return ret;
+ } else if (_.GetOperandTypeId(inst, operand_index) != result_type)
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected arithmetic operands to be of Result Type: "
<< spvOpcodeString(opcode) << " operand index "
@@ -91,7 +118,10 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
(opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem &&
opcode != spv::Op::OpSMod);
if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
- !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)))
+ !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) &&
+ !(opcode == spv::Op::OpIMul &&
+ _.IsCooperativeMatrixKHRType(result_type) &&
+ _.IsIntCooperativeMatrixType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as Result Type: "
<< spvOpcodeString(opcode);
@@ -102,9 +132,26 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
for (size_t operand_index = 2; operand_index < inst->operands().size();
++operand_index) {
const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
+
+ if (supportsCoopMat && _.IsCooperativeMatrixKHRType(result_type)) {
+ if (!_.IsCooperativeMatrixKHRType(type_id) ||
+ !_.IsIntCooperativeMatrixType(type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected arithmetic operands to be of Result Type: "
+ << spvOpcodeString(opcode) << " operand index "
+ << operand_index;
+ }
+ spv_result_t ret =
+ _.CooperativeMatrixShapesMatch(inst, type_id, result_type);
+ if (ret != SPV_SUCCESS) return ret;
+ }
+
if (!type_id ||
(!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) &&
- !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type))))
+ !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)) &&
+ !(opcode == spv::Op::OpIMul &&
+ _.IsCooperativeMatrixKHRType(result_type) &&
+ _.IsIntCooperativeMatrixType(result_type))))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected int scalar or vector type as operand: "
<< spvOpcodeString(opcode) << " operand index "
@@ -187,7 +234,7 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpMatrixTimesScalar: {
if (!_.IsFloatMatrixType(result_type) &&
- !_.IsCooperativeMatrixType(result_type))
+ !(_.IsCooperativeMatrixType(result_type)))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected float matrix type as Result Type: "
<< spvOpcodeString(opcode);
@@ -459,22 +506,108 @@ spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
const uint32_t B_type_id = _.GetOperandTypeId(inst, 3);
const uint32_t C_type_id = _.GetOperandTypeId(inst, 4);
- if (!_.IsCooperativeMatrixType(A_type_id)) {
+ if (!_.IsCooperativeMatrixNVType(A_type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative matrix type as A Type: "
<< spvOpcodeString(opcode);
}
- if (!_.IsCooperativeMatrixType(B_type_id)) {
+ if (!_.IsCooperativeMatrixNVType(B_type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative matrix type as B Type: "
<< spvOpcodeString(opcode);
}
- if (!_.IsCooperativeMatrixType(C_type_id)) {
+ if (!_.IsCooperativeMatrixNVType(C_type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative matrix type as C Type: "
<< spvOpcodeString(opcode);
}
- if (!_.IsCooperativeMatrixType(D_type_id)) {
+ if (!_.IsCooperativeMatrixNVType(D_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected cooperative matrix type as Result Type: "
+ << spvOpcodeString(opcode);
+ }
+
+ const auto A = _.FindDef(A_type_id);
+ const auto B = _.FindDef(B_type_id);
+ const auto C = _.FindDef(C_type_id);
+ const auto D = _.FindDef(D_type_id);
+
+ std::tuple<bool, bool, uint32_t> A_scope, B_scope, C_scope, D_scope,
+ A_rows, B_rows, C_rows, D_rows, A_cols, B_cols, C_cols, D_cols;
+
+ A_scope = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(2));
+ B_scope = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(2));
+ C_scope = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(2));
+ D_scope = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(2));
+
+ A_rows = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(3));
+ B_rows = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(3));
+ C_rows = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(3));
+ D_rows = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(3));
+
+ A_cols = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(4));
+ B_cols = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(4));
+ C_cols = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(4));
+ D_cols = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(4));
+
+ const auto notEqual = [](std::tuple<bool, bool, uint32_t> X,
+ std::tuple<bool, bool, uint32_t> Y) {
+ return (std::get<1>(X) && std::get<1>(Y) &&
+ std::get<2>(X) != std::get<2>(Y));
+ };
+
+ if (notEqual(A_scope, B_scope) || notEqual(A_scope, C_scope) ||
+ notEqual(A_scope, D_scope) || notEqual(B_scope, C_scope) ||
+ notEqual(B_scope, D_scope) || notEqual(C_scope, D_scope)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix scopes must match: "
+ << spvOpcodeString(opcode);
+ }
+
+ if (notEqual(A_rows, C_rows) || notEqual(A_rows, D_rows) ||
+ notEqual(C_rows, D_rows)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix 'M' mismatch: "
+ << spvOpcodeString(opcode);
+ }
+
+ if (notEqual(B_cols, C_cols) || notEqual(B_cols, D_cols) ||
+ notEqual(C_cols, D_cols)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix 'N' mismatch: "
+ << spvOpcodeString(opcode);
+ }
+
+ if (notEqual(A_cols, B_rows)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix 'K' mismatch: "
+ << spvOpcodeString(opcode);
+ }
+ break;
+ }
+
+ case spv::Op::OpCooperativeMatrixMulAddKHR: {
+ const uint32_t D_type_id = _.GetOperandTypeId(inst, 1);
+ const uint32_t A_type_id = _.GetOperandTypeId(inst, 2);
+ const uint32_t B_type_id = _.GetOperandTypeId(inst, 3);
+ const uint32_t C_type_id = _.GetOperandTypeId(inst, 4);
+
+ if (!_.IsCooperativeMatrixAType(A_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix type must be A Type: "
+ << spvOpcodeString(opcode);
+ }
+ if (!_.IsCooperativeMatrixBType(B_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix type must be B Type: "
+ << spvOpcodeString(opcode);
+ }
+ if (!_.IsCooperativeMatrixAccType(C_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix type must be Accumulator Type: "
+ << spvOpcodeString(opcode);
+ }
+ if (!_.IsCooperativeMatrixKHRType(D_type_id)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative matrix type as Result Type: "
<< spvOpcodeString(opcode);
diff --git a/third_party/SPIRV-Tools/source/val/validate_atomics.cpp b/third_party/SPIRV-Tools/source/val/validate_atomics.cpp
index b745a9ec1..8ddef1789 100644
--- a/third_party/SPIRV-Tools/source/val/validate_atomics.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_atomics.cpp
@@ -144,12 +144,13 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpAtomicFlagClear: {
const uint32_t result_type = inst->type_id();
- // All current atomics only are scalar result
// Validate return type first so can just check if pointer type is same
// (if applicable)
if (HasReturnType(opcode)) {
if (HasOnlyFloatReturnType(opcode) &&
- !_.IsFloatScalarType(result_type)) {
+ (!(_.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
+ _.IsFloat16Vector2Or4Type(result_type)) &&
+ !_.IsFloatScalarType(result_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
<< ": expected Result Type to be float scalar type";
@@ -160,6 +161,9 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
<< ": expected Result Type to be integer scalar type";
} else if (HasIntOrFloatReturnType(opcode) &&
!_.IsFloatScalarType(result_type) &&
+ !(opcode == spv::Op::OpAtomicExchange &&
+ _.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
+ _.IsFloat16Vector2Or4Type(result_type)) &&
!_.IsIntScalarType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
@@ -222,12 +226,21 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
if (opcode == spv::Op::OpAtomicFAddEXT) {
// result type being float checked already
- if ((_.GetBitWidth(result_type) == 16) &&
- (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT))) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << spvOpcodeString(opcode)
- << ": float add atomics require the AtomicFloat32AddEXT "
- "capability";
+ if (_.GetBitWidth(result_type) == 16) {
+ if (_.IsFloat16Vector2Or4Type(result_type)) {
+ if (!_.HasCapability(spv::Capability::AtomicFloat16VectorNV))
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float vector atomics require the "
+ "AtomicFloat16VectorNV capability";
+ } else {
+ if (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float add atomics require the AtomicFloat32AddEXT "
+ "capability";
+ }
+ }
}
if ((_.GetBitWidth(result_type) == 32) &&
(!_.HasCapability(spv::Capability::AtomicFloat32AddEXT))) {
@@ -245,12 +258,21 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
}
} else if (opcode == spv::Op::OpAtomicFMinEXT ||
opcode == spv::Op::OpAtomicFMaxEXT) {
- if ((_.GetBitWidth(result_type) == 16) &&
- (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT))) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << spvOpcodeString(opcode)
- << ": float min/max atomics require the "
- "AtomicFloat16MinMaxEXT capability";
+ if (_.GetBitWidth(result_type) == 16) {
+ if (_.IsFloat16Vector2Or4Type(result_type)) {
+ if (!_.HasCapability(spv::Capability::AtomicFloat16VectorNV))
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float vector atomics require the "
+ "AtomicFloat16VectorNV capability";
+ } else {
+ if (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << spvOpcodeString(opcode)
+ << ": float min/max atomics require the "
+ "AtomicFloat16MinMaxEXT capability";
+ }
+ }
}
if ((_.GetBitWidth(result_type) == 32) &&
(!_.HasCapability(spv::Capability::AtomicFloat32MinMaxEXT))) {
diff --git a/third_party/SPIRV-Tools/source/val/validate_builtins.cpp b/third_party/SPIRV-Tools/source/val/validate_builtins.cpp
index 3e8171250..a7e9942a0 100644
--- a/third_party/SPIRV-Tools/source/val/validate_builtins.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_builtins.cpp
@@ -118,13 +118,15 @@ typedef enum VUIDError_ {
VUIDErrorMax,
} VUIDError;
-const static uint32_t NumVUIDBuiltins = 36;
+const static uint32_t NumVUIDBuiltins = 39;
typedef struct {
spv::BuiltIn builtIn;
uint32_t vuid[VUIDErrorMax]; // execution mode, storage class, type VUIDs
} BuiltinVUIDMapping;
+// Many built-ins have the same checks (Storage Class, Type, etc)
+// This table provides a nice LUT for the VUIDs
std::array<BuiltinVUIDMapping, NumVUIDBuiltins> builtinVUIDInfo = {{
// clang-format off
{spv::BuiltIn::SubgroupEqMask, {0, 4370, 4371}},
@@ -163,8 +165,11 @@ std::array<BuiltinVUIDMapping, NumVUIDBuiltins> builtinVUIDInfo = {{
{spv::BuiltIn::CullMaskKHR, {6735, 6736, 6737}},
{spv::BuiltIn::BaryCoordKHR, {4154, 4155, 4156}},
{spv::BuiltIn::BaryCoordNoPerspKHR, {4160, 4161, 4162}},
- // clang-format off
-} };
+ {spv::BuiltIn::PrimitivePointIndicesEXT, {7041, 7043, 7044}},
+ {spv::BuiltIn::PrimitiveLineIndicesEXT, {7047, 7049, 7050}},
+ {spv::BuiltIn::PrimitiveTriangleIndicesEXT, {7053, 7055, 7056}},
+ // clang-format on
+}};
uint32_t GetVUIDForBuiltin(spv::BuiltIn builtIn, VUIDError type) {
uint32_t vuid = 0;
@@ -356,6 +361,9 @@ class BuiltInsValidator {
spv_result_t ValidateRayTracingBuiltinsAtDefinition(
const Decoration& decoration, const Instruction& inst);
+ spv_result_t ValidateMeshShadingEXTBuiltinsAtDefinition(
+ const Decoration& decoration, const Instruction& inst);
+
// The following section contains functions which are called when id defined
// by |referenced_inst| is
// 1. referenced by |referenced_from_inst|
@@ -546,6 +554,11 @@ class BuiltInsValidator {
const Instruction& referenced_inst,
const Instruction& referenced_from_inst);
+ spv_result_t ValidateMeshShadingEXTBuiltinsAtReference(
+ const Decoration& decoration, const Instruction& built_in_inst,
+ const Instruction& referenced_inst,
+ const Instruction& referenced_from_inst);
+
// Validates that |built_in_inst| is not (even indirectly) referenced from
// within a function which can be called with |execution_model|.
//
@@ -581,6 +594,10 @@ class BuiltInsValidator {
spv_result_t ValidateI32Arr(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag);
+ spv_result_t ValidateArrayedI32Vec(
+ const Decoration& decoration, const Instruction& inst,
+ uint32_t num_components,
+ const std::function<spv_result_t(const std::string& message)>& diag);
spv_result_t ValidateOptionalArrayedI32(
const Decoration& decoration, const Instruction& inst,
const std::function<spv_result_t(const std::string& message)>& diag);
@@ -909,6 +926,45 @@ spv_result_t BuiltInsValidator::ValidateI32Vec(
return SPV_SUCCESS;
}
+spv_result_t BuiltInsValidator::ValidateArrayedI32Vec(
+ const Decoration& decoration, const Instruction& inst,
+ uint32_t num_components,
+ const std::function<spv_result_t(const std::string& message)>& diag) {
+ uint32_t underlying_type = 0;
+ if (spv_result_t error =
+ GetUnderlyingType(_, decoration, inst, &underlying_type)) {
+ return error;
+ }
+
+ const Instruction* const type_inst = _.FindDef(underlying_type);
+ if (type_inst->opcode() != spv::Op::OpTypeArray) {
+ return diag(GetDefinitionDesc(decoration, inst) + " is not an array.");
+ }
+
+ const uint32_t component_type = type_inst->word(2);
+ if (!_.IsIntVectorType(component_type)) {
+ return diag(GetDefinitionDesc(decoration, inst) + " is not an int vector.");
+ }
+
+ const uint32_t actual_num_components = _.GetDimension(component_type);
+ if (_.GetDimension(component_type) != num_components) {
+ std::ostringstream ss;
+ ss << GetDefinitionDesc(decoration, inst) << " has "
+ << actual_num_components << " components.";
+ return diag(ss.str());
+ }
+
+ const uint32_t bit_width = _.GetBitWidth(component_type);
+ if (bit_width != 32) {
+ std::ostringstream ss;
+ ss << GetDefinitionDesc(decoration, inst)
+ << " has components with bit width " << bit_width << ".";
+ return diag(ss.str());
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t BuiltInsValidator::ValidateOptionalArrayedF32Vec(
const Decoration& decoration, const Instruction& inst,
uint32_t num_components,
@@ -1064,7 +1120,7 @@ spv_result_t BuiltInsValidator::ValidateF32ArrHelper(
if (num_components != 0) {
uint64_t actual_num_components = 0;
- if (!_.GetConstantValUint64(type_inst->word(3), &actual_num_components)) {
+ if (!_.EvalConstantValUint64(type_inst->word(3), &actual_num_components)) {
assert(0 && "Array type definition is corrupt");
}
if (actual_num_components != num_components) {
@@ -4108,6 +4164,119 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference(
return SPV_SUCCESS;
}
+spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition(
+ const Decoration& decoration, const Instruction& inst) {
+ if (spvIsVulkanEnv(_.context()->target_env)) {
+ const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
+ uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType);
+ if (builtin == spv::BuiltIn::PrimitivePointIndicesEXT) {
+ if (spv_result_t error = ValidateI32Arr(
+ decoration, inst,
+ [this, &inst, &decoration,
+ &vuid](const std::string& message) -> spv_result_t {
+ return _.diag(SPV_ERROR_INVALID_DATA, &inst)
+ << _.VkErrorID(vuid) << "According to the "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec BuiltIn "
+ << _.grammar().lookupOperandName(
+ SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
+ << " variable needs to be a 32-bit int array."
+ << message;
+ })) {
+ return error;
+ }
+ }
+ if (builtin == spv::BuiltIn::PrimitiveLineIndicesEXT) {
+ if (spv_result_t error = ValidateArrayedI32Vec(
+ decoration, inst, 2,
+ [this, &inst, &decoration,
+ &vuid](const std::string& message) -> spv_result_t {
+ return _.diag(SPV_ERROR_INVALID_DATA, &inst)
+ << _.VkErrorID(vuid) << "According to the "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec BuiltIn "
+ << _.grammar().lookupOperandName(
+ SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
+ << " variable needs to be a 2-component 32-bit int "
+ "array."
+ << message;
+ })) {
+ return error;
+ }
+ }
+ if (builtin == spv::BuiltIn::PrimitiveTriangleIndicesEXT) {
+ if (spv_result_t error = ValidateArrayedI32Vec(
+ decoration, inst, 3,
+ [this, &inst, &decoration,
+ &vuid](const std::string& message) -> spv_result_t {
+ return _.diag(SPV_ERROR_INVALID_DATA, &inst)
+ << _.VkErrorID(vuid) << "According to the "
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec BuiltIn "
+ << _.grammar().lookupOperandName(
+ SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0])
+ << " variable needs to be a 3-component 32-bit int "
+ "array."
+ << message;
+ })) {
+ return error;
+ }
+ }
+ }
+ // Seed at reference checks with this built-in.
+ return ValidateMeshShadingEXTBuiltinsAtReference(decoration, inst, inst,
+ inst);
+}
+
+spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference(
+ const Decoration& decoration, const Instruction& built_in_inst,
+ const Instruction& referenced_inst,
+ const Instruction& referenced_from_inst) {
+ if (spvIsVulkanEnv(_.context()->target_env)) {
+ const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]);
+ const spv::StorageClass storage_class =
+ GetStorageClass(referenced_from_inst);
+ if (storage_class != spv::StorageClass::Max &&
+ storage_class != spv::StorageClass::Output) {
+ uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorStorageClass);
+ return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
+ << _.VkErrorID(vuid) << spvLogStringForEnv(_.context()->target_env)
+ << " spec allows BuiltIn "
+ << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
+ uint32_t(builtin))
+ << " to be only used for variables with Output storage class. "
+ << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
+ referenced_from_inst)
+ << " " << GetStorageClassDesc(referenced_from_inst);
+ }
+
+ for (const spv::ExecutionModel execution_model : execution_models_) {
+ if (execution_model != spv::ExecutionModel::MeshEXT) {
+ uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
+ return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
+ << _.VkErrorID(vuid)
+ << spvLogStringForEnv(_.context()->target_env)
+ << " spec allows BuiltIn "
+ << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
+ uint32_t(builtin))
+ << " to be used only with MeshEXT execution model. "
+ << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
+ referenced_from_inst, execution_model);
+ }
+ }
+ }
+
+ if (function_id_ == 0) {
+ // Propagate this rule to all dependant ids in the global scope.
+ id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
+ std::bind(&BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference,
+ this, decoration, built_in_inst, referenced_from_inst,
+ std::placeholders::_1));
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
const Decoration& decoration, const Instruction& inst) {
const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]);
@@ -4283,6 +4452,11 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case spv::BuiltIn::CullMaskKHR: {
return ValidateRayTracingBuiltinsAtDefinition(decoration, inst);
}
+ case spv::BuiltIn::PrimitivePointIndicesEXT:
+ case spv::BuiltIn::PrimitiveLineIndicesEXT:
+ case spv::BuiltIn::PrimitiveTriangleIndicesEXT: {
+ return ValidateMeshShadingEXTBuiltinsAtDefinition(decoration, inst);
+ }
case spv::BuiltIn::PrimitiveShadingRateKHR: {
return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
}
diff --git a/third_party/SPIRV-Tools/source/val/validate_capability.cpp b/third_party/SPIRV-Tools/source/val/validate_capability.cpp
index 98dab4237..81d2ad52d 100644
--- a/third_party/SPIRV-Tools/source/val/validate_capability.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_capability.cpp
@@ -240,7 +240,7 @@ bool IsEnabledByExtension(ValidationState_t& _, uint32_t capability) {
ExtensionSet operand_exts(operand_desc->numExtensions,
operand_desc->extensions);
- if (operand_exts.IsEmpty()) return false;
+ if (operand_exts.empty()) return false;
return _.HasAnyOfExtensions(operand_exts);
}
diff --git a/third_party/SPIRV-Tools/source/val/validate_cfg.cpp b/third_party/SPIRV-Tools/source/val/validate_cfg.cpp
index 7b3f7480f..9b7161fc4 100644
--- a/third_party/SPIRV-Tools/source/val/validate_cfg.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_cfg.cpp
@@ -190,6 +190,8 @@ spv_result_t ValidateBranchConditional(ValidationState_t& _,
"ID of an OpLabel instruction";
}
+ // A similar requirement for SPV_KHR_maximal_reconvergence is deferred until
+ // entry point call trees have been reconrded.
if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && true_id == false_id) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "In SPIR-V 1.6 or later, True Label and False Label must be "
@@ -875,6 +877,95 @@ spv_result_t StructuredControlFlowChecks(
return SPV_SUCCESS;
}
+spv_result_t MaximalReconvergenceChecks(ValidationState_t& _) {
+ // Find all the entry points with the MaximallyReconvergencesKHR execution
+ // mode.
+ std::unordered_set<uint32_t> maximal_funcs;
+ std::unordered_set<uint32_t> maximal_entry_points;
+ for (auto entry_point : _.entry_points()) {
+ const auto* exec_modes = _.GetExecutionModes(entry_point);
+ if (exec_modes &&
+ exec_modes->count(spv::ExecutionMode::MaximallyReconvergesKHR)) {
+ maximal_entry_points.insert(entry_point);
+ maximal_funcs.insert(entry_point);
+ }
+ }
+
+ if (maximal_entry_points.empty()) {
+ return SPV_SUCCESS;
+ }
+
+ // Find all the functions reachable from a maximal reconvergence entry point.
+ for (const auto& func : _.functions()) {
+ const auto& entry_points = _.EntryPointReferences(func.id());
+ for (auto id : entry_points) {
+ if (maximal_entry_points.count(id)) {
+ maximal_funcs.insert(func.id());
+ break;
+ }
+ }
+ }
+
+ // Check for conditional branches with the same true and false targets.
+ for (const auto& inst : _.ordered_instructions()) {
+ if (inst.opcode() == spv::Op::OpBranchConditional) {
+ const auto true_id = inst.GetOperandAs<uint32_t>(1);
+ const auto false_id = inst.GetOperandAs<uint32_t>(2);
+ if (true_id == false_id && maximal_funcs.count(inst.function()->id())) {
+ return _.diag(SPV_ERROR_INVALID_ID, &inst)
+ << "In entry points using the MaximallyReconvergesKHR execution "
+ "mode, True Label and False Label must be different labels";
+ }
+ }
+ }
+
+ // Check for invalid multiple predecessors. Only loop headers, continue
+ // targets, merge targets or switch targets or defaults may have multiple
+ // unique predecessors.
+ for (const auto& func : _.functions()) {
+ if (!maximal_funcs.count(func.id())) continue;
+
+ for (const auto* block : func.ordered_blocks()) {
+ std::unordered_set<uint32_t> unique_preds;
+ const auto* preds = block->predecessors();
+ if (!preds) continue;
+
+ for (const auto* pred : *preds) {
+ unique_preds.insert(pred->id());
+ }
+ if (unique_preds.size() < 2) continue;
+
+ const auto* terminator = block->terminator();
+ const auto index = terminator - &_.ordered_instructions()[0];
+ const auto* pre_terminator = &_.ordered_instructions()[index - 1];
+ if (pre_terminator->opcode() == spv::Op::OpLoopMerge) continue;
+
+ const auto* label = _.FindDef(block->id());
+ bool ok = false;
+ for (const auto& pair : label->uses()) {
+ const auto* use_inst = pair.first;
+ switch (use_inst->opcode()) {
+ case spv::Op::OpSelectionMerge:
+ case spv::Op::OpLoopMerge:
+ case spv::Op::OpSwitch:
+ ok = true;
+ break;
+ default:
+ break;
+ }
+ }
+ if (!ok) {
+ return _.diag(SPV_ERROR_INVALID_CFG, label)
+ << "In entry points using the MaximallyReconvergesKHR "
+ "execution mode, this basic block must not have multiple "
+ "unique predecessors";
+ }
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t PerformCfgChecks(ValidationState_t& _) {
for (auto& function : _.functions()) {
// Check all referenced blocks are defined within a function
@@ -999,6 +1090,11 @@ spv_result_t PerformCfgChecks(ValidationState_t& _) {
return error;
}
}
+
+ if (auto error = MaximalReconvergenceChecks(_)) {
+ return error;
+ }
+
return SPV_SUCCESS;
}
diff --git a/third_party/SPIRV-Tools/source/val/validate_composites.cpp b/third_party/SPIRV-Tools/source/val/validate_composites.cpp
index 2b83c63dd..26486dac7 100644
--- a/third_party/SPIRV-Tools/source/val/validate_composites.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_composites.cpp
@@ -94,7 +94,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _,
break;
}
- if (!_.GetConstantValUint64(type_inst->word(3), &array_size)) {
+ if (!_.EvalConstantValUint64(type_inst->word(3), &array_size)) {
assert(0 && "Array type definition is corrupt");
}
if (component_index >= array_size) {
@@ -122,6 +122,7 @@ spv_result_t GetExtractInsertValueType(ValidationState_t& _,
*member_type = type_inst->word(component_index + 2);
break;
}
+ case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeMatrixNV: {
*member_type = type_inst->word(2);
break;
@@ -288,7 +289,7 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _,
}
uint64_t array_size = 0;
- if (!_.GetConstantValUint64(array_inst->word(3), &array_size)) {
+ if (!_.EvalConstantValUint64(array_inst->word(3), &array_size)) {
assert(0 && "Array type definition is corrupt");
}
@@ -335,6 +336,25 @@ spv_result_t ValidateCompositeConstruct(ValidationState_t& _,
break;
}
+ case spv::Op::OpTypeCooperativeMatrixKHR: {
+ const auto result_type_inst = _.FindDef(result_type);
+ assert(result_type_inst);
+ const auto component_type_id =
+ result_type_inst->GetOperandAs<uint32_t>(1);
+
+ if (3 != num_operands) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Must be only one constituent";
+ }
+
+ const uint32_t operand_type_id = _.GetOperandTypeId(inst, 2);
+
+ if (operand_type_id != component_type_id) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected Constituent type to be equal to the component type";
+ }
+ break;
+ }
case spv::Op::OpTypeCooperativeMatrixNV: {
const auto result_type_inst = _.FindDef(result_type);
assert(result_type_inst);
diff --git a/third_party/SPIRV-Tools/source/val/validate_constants.cpp b/third_party/SPIRV-Tools/source/val/validate_constants.cpp
index 006e504c0..4deaa4968 100644
--- a/third_party/SPIRV-Tools/source/val/validate_constants.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_constants.cpp
@@ -243,6 +243,7 @@ spv_result_t ValidateConstantComposite(ValidationState_t& _,
}
}
} break;
+ case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeCooperativeMatrixNV: {
if (1 != constituent_count) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
@@ -310,6 +311,7 @@ bool IsTypeNullable(const std::vector<uint32_t>& instruction,
case spv::Op::OpTypeArray:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeVector: {
auto base_type = _.FindDef(instruction[2]);
return base_type && IsTypeNullable(base_type->words(), _);
diff --git a/third_party/SPIRV-Tools/source/val/validate_conversion.cpp b/third_party/SPIRV-Tools/source/val/validate_conversion.cpp
index 476c1fe8b..b2892a863 100644
--- a/third_party/SPIRV-Tools/source/val/validate_conversion.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_conversion.cpp
@@ -473,7 +473,10 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
const bool input_is_pointer = _.IsPointerType(input_type);
const bool input_is_int_scalar = _.IsIntScalarType(input_type);
- if (!result_is_pointer && !result_is_int_scalar &&
+ const bool result_is_coopmat = _.IsCooperativeMatrixType(result_type);
+ const bool input_is_coopmat = _.IsCooperativeMatrixType(input_type);
+
+ if (!result_is_pointer && !result_is_int_scalar && !result_is_coopmat &&
!_.IsIntVectorType(result_type) &&
!_.IsFloatScalarType(result_type) &&
!_.IsFloatVectorType(result_type))
@@ -481,13 +484,24 @@ spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
<< "Expected Result Type to be a pointer or int or float vector "
<< "or scalar type: " << spvOpcodeString(opcode);
- if (!input_is_pointer && !input_is_int_scalar &&
+ if (!input_is_pointer && !input_is_int_scalar && !input_is_coopmat &&
!_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) &&
!_.IsFloatVectorType(input_type))
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected input to be a pointer or int or float vector "
<< "or scalar: " << spvOpcodeString(opcode);
+ if (result_is_coopmat != input_is_coopmat)
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Cooperative matrix can only be cast to another cooperative "
+ << "matrix: " << spvOpcodeString(opcode);
+
+ if (result_is_coopmat) {
+ spv_result_t ret =
+ _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
+ if (ret != SPV_SUCCESS) return ret;
+ }
+
if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 5) ||
_.HasExtension(kSPV_KHR_physical_storage_buffer)) {
const bool result_is_int_vector = _.IsIntVectorType(result_type);
diff --git a/third_party/SPIRV-Tools/source/val/validate_decorations.cpp b/third_party/SPIRV-Tools/source/val/validate_decorations.cpp
index c1fca45f9..0a7df6581 100644
--- a/third_party/SPIRV-Tools/source/val/validate_decorations.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_decorations.cpp
@@ -452,7 +452,16 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
return ds;
};
- const auto& members = getStructMembers(struct_id, vstate);
+ // If we are checking physical storage buffer pointers, we may not actually
+ // have a struct here. Instead, pretend we have a struct with a single member
+ // at offset 0.
+ const auto& struct_type = vstate.FindDef(struct_id);
+ std::vector<uint32_t> members;
+ if (struct_type->opcode() == spv::Op::OpTypeStruct) {
+ members = getStructMembers(struct_id, vstate);
+ } else {
+ members.push_back(struct_id);
+ }
// To check for member overlaps, we want to traverse the members in
// offset order.
@@ -461,31 +470,38 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
uint32_t offset;
};
std::vector<MemberOffsetPair> member_offsets;
- member_offsets.reserve(members.size());
- for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size());
- memberIdx < numMembers; memberIdx++) {
- uint32_t offset = 0xffffffff;
- auto member_decorations =
- vstate.id_member_decorations(struct_id, memberIdx);
- for (auto decoration = member_decorations.begin;
- decoration != member_decorations.end; ++decoration) {
- assert(decoration->struct_member_index() == (int)memberIdx);
- switch (decoration->dec_type()) {
- case spv::Decoration::Offset:
- offset = decoration->params()[0];
- break;
- default:
- break;
+
+ // With physical storage buffers, we might be checking layouts that do not
+ // originate from a structure.
+ if (struct_type->opcode() == spv::Op::OpTypeStruct) {
+ member_offsets.reserve(members.size());
+ for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size());
+ memberIdx < numMembers; memberIdx++) {
+ uint32_t offset = 0xffffffff;
+ auto member_decorations =
+ vstate.id_member_decorations(struct_id, memberIdx);
+ for (auto decoration = member_decorations.begin;
+ decoration != member_decorations.end; ++decoration) {
+ assert(decoration->struct_member_index() == (int)memberIdx);
+ switch (decoration->dec_type()) {
+ case spv::Decoration::Offset:
+ offset = decoration->params()[0];
+ break;
+ default:
+ break;
+ }
}
+ member_offsets.push_back(
+ MemberOffsetPair{memberIdx, incoming_offset + offset});
}
- member_offsets.push_back(
- MemberOffsetPair{memberIdx, incoming_offset + offset});
+ std::stable_sort(
+ member_offsets.begin(), member_offsets.end(),
+ [](const MemberOffsetPair& lhs, const MemberOffsetPair& rhs) {
+ return lhs.offset < rhs.offset;
+ });
+ } else {
+ member_offsets.push_back({0, 0});
}
- std::stable_sort(
- member_offsets.begin(), member_offsets.end(),
- [](const MemberOffsetPair& lhs, const MemberOffsetPair& rhs) {
- return lhs.offset < rhs.offset;
- });
// Now scan from lowest offset to highest offset.
uint32_t nextValidOffset = 0;
@@ -906,9 +922,9 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
}
}
- if (vstate.HasCapability(
- spv::Capability::WorkgroupMemoryExplicitLayoutKHR) &&
- num_workgroup_variables > 0 &&
+ const bool workgroup_blocks_allowed = vstate.HasCapability(
+ spv::Capability::WorkgroupMemoryExplicitLayoutKHR);
+ if (workgroup_blocks_allowed && num_workgroup_variables > 0 &&
num_workgroup_variables_with_block > 0) {
if (num_workgroup_variables != num_workgroup_variables_with_block) {
return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point))
@@ -929,6 +945,13 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
"Entry point id "
<< entry_point << " does not meet this requirement.";
}
+ } else if (!workgroup_blocks_allowed &&
+ num_workgroup_variables_with_block > 0) {
+ return vstate.diag(SPV_ERROR_INVALID_BINARY,
+ vstate.FindDef(entry_point))
+ << "Workgroup Storage Class variables can't be decorated with "
+ "Block unless declaring the WorkgroupMemoryExplicitLayoutKHR "
+ "capability.";
}
}
}
@@ -1023,6 +1046,8 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
std::unordered_set<uint32_t> uses_push_constant;
for (const auto& inst : vstate.ordered_instructions()) {
const auto& words = inst.words();
+ auto type_id = inst.type_id();
+ const Instruction* type_inst = vstate.FindDef(type_id);
if (spv::Op::OpVariable == inst.opcode()) {
const auto var_id = inst.id();
// For storage class / decoration combinations, see Vulkan 14.5.4 "Offset
@@ -1276,6 +1301,23 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
}
}
}
+ } else if (type_inst && type_inst->opcode() == spv::Op::OpTypePointer &&
+ type_inst->GetOperandAs<spv::StorageClass>(1u) ==
+ spv::StorageClass::PhysicalStorageBuffer) {
+ const bool scalar_block_layout = vstate.options()->scalar_block_layout;
+ MemberConstraints constraints;
+ const bool buffer = true;
+ const auto data_type_id = type_inst->GetOperandAs<uint32_t>(2u);
+ const auto* data_type_inst = vstate.FindDef(data_type_id);
+ if (data_type_inst->opcode() == spv::Op::OpTypeStruct) {
+ ComputeMemberConstraintsForStruct(&constraints, data_type_id,
+ LayoutConstraints(), vstate);
+ }
+ if (auto res = checkLayout(data_type_id, "PhysicalStorageBuffer", "Block",
+ !buffer, scalar_block_layout, 0, constraints,
+ vstate)) {
+ return res;
+ }
}
}
return SPV_SUCCESS;
@@ -1283,21 +1325,14 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
// Returns true if |decoration| cannot be applied to the same id more than once.
bool AtMostOncePerId(spv::Decoration decoration) {
- return decoration == spv::Decoration::ArrayStride;
+ return decoration != spv::Decoration::UserSemantic &&
+ decoration != spv::Decoration::FuncParamAttr;
}
// Returns true if |decoration| cannot be applied to the same member more than
// once.
bool AtMostOncePerMember(spv::Decoration decoration) {
- switch (decoration) {
- case spv::Decoration::Offset:
- case spv::Decoration::MatrixStride:
- case spv::Decoration::RowMajor:
- case spv::Decoration::ColMajor:
- return true;
- default:
- return false;
- }
+ return decoration != spv::Decoration::UserSemantic;
}
spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) {
@@ -1514,7 +1549,8 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate,
const auto opcode = inst.opcode();
const auto type_id = inst.type_id();
if (opcode != spv::Op::OpVariable &&
- opcode != spv::Op::OpFunctionParameter) {
+ opcode != spv::Op::OpFunctionParameter &&
+ opcode != spv::Op::OpRawAccessChainNV) {
return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
<< "Target of NonWritable decoration must be a memory object "
"declaration (a variable or a function parameter)";
@@ -1527,10 +1563,11 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate,
vstate.features().nonwritable_var_in_function_or_private) {
// New permitted feature in SPIR-V 1.4.
} else if (
- // It may point to a UBO, SSBO, or storage image.
+ // It may point to a UBO, SSBO, storage image, or raw access chain.
vstate.IsPointerToUniformBlock(type_id) ||
vstate.IsPointerToStorageBuffer(type_id) ||
- vstate.IsPointerToStorageImage(type_id)) {
+ vstate.IsPointerToStorageImage(type_id) ||
+ opcode == spv::Op::OpRawAccessChainNV) {
} else {
return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
<< "Target of NonWritable decoration is invalid: must point to a "
diff --git a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
index 0ac62bfc8..7b73c9c6e 100644
--- a/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_extensions.cpp
@@ -482,8 +482,8 @@ spv_result_t ValidateClspvReflectionArgumentBuffer(ValidationState_t& _,
return SPV_SUCCESS;
}
-spv_result_t ValidateClspvReflectionArgumentOffsetBuffer(ValidationState_t& _,
- const Instruction* inst) {
+spv_result_t ValidateClspvReflectionArgumentOffsetBuffer(
+ ValidationState_t& _, const Instruction* inst) {
const auto num_operands = inst->operands().size();
if (auto error = ValidateKernelDecl(_, inst)) {
return error;
@@ -802,7 +802,7 @@ spv_result_t ValidateClspvReflectionPushConstantData(ValidationState_t& _,
}
spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _,
- const Instruction* inst) {
+ const Instruction* inst) {
if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "PrintfID must be a 32-bit unsigned integer OpConstant";
@@ -823,8 +823,8 @@ spv_result_t ValidateClspvReflectionPrintfInfo(ValidationState_t& _,
return SPV_SUCCESS;
}
-spv_result_t ValidateClspvReflectionPrintfStorageBuffer(ValidationState_t& _,
- const Instruction* inst) {
+spv_result_t ValidateClspvReflectionPrintfStorageBuffer(
+ ValidationState_t& _, const Instruction* inst) {
if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "DescriptorSet must be a 32-bit unsigned integer OpConstant";
@@ -843,8 +843,8 @@ spv_result_t ValidateClspvReflectionPrintfStorageBuffer(ValidationState_t& _,
return SPV_SUCCESS;
}
-spv_result_t ValidateClspvReflectionPrintfPushConstant(ValidationState_t& _,
- const Instruction* inst) {
+spv_result_t ValidateClspvReflectionPrintfPushConstant(
+ ValidationState_t& _, const Instruction* inst) {
if (!IsUint32Constant(_, inst->GetOperandAs<uint32_t>(4))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Offset must be a 32-bit unsigned integer OpConstant";
@@ -3100,7 +3100,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
uint32_t vector_count = inst->word(6);
uint64_t const_val;
- if (!_.GetConstantValUint64(vector_count, &const_val)) {
+ if (!_.EvalConstantValUint64(vector_count, &const_val)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name()
<< ": Vector Count must be 32-bit integer OpConstant";
@@ -3168,16 +3168,16 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
break;
}
case CommonDebugInfoDebugTypePointer: {
- auto validate_base_type =
- ValidateOperandBaseType(_, inst, 5, ext_inst_name);
+ auto validate_base_type = ValidateOperandDebugType(
+ _, "Base Type", inst, 5, ext_inst_name, false);
if (validate_base_type != SPV_SUCCESS) return validate_base_type;
CHECK_CONST_UINT_OPERAND("Storage Class", 6);
CHECK_CONST_UINT_OPERAND("Flags", 7);
break;
}
case CommonDebugInfoDebugTypeQualifier: {
- auto validate_base_type =
- ValidateOperandBaseType(_, inst, 5, ext_inst_name);
+ auto validate_base_type = ValidateOperandDebugType(
+ _, "Base Type", inst, 5, ext_inst_name, false);
if (validate_base_type != SPV_SUCCESS) return validate_base_type;
CHECK_CONST_UINT_OPERAND("Type Qualifier", 6);
break;
@@ -3191,7 +3191,7 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
uint32_t component_count = inst->word(6);
if (vulkanDebugInfo) {
uint64_t const_val;
- if (!_.GetConstantValUint64(component_count, &const_val)) {
+ if (!_.EvalConstantValUint64(component_count, &const_val)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name()
<< ": Component Count must be 32-bit integer OpConstant";
diff --git a/third_party/SPIRV-Tools/source/val/validate_id.cpp b/third_party/SPIRV-Tools/source/val/validate_id.cpp
index 92a4e8e33..bcfeb5915 100644
--- a/third_party/SPIRV-Tools/source/val/validate_id.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_id.cpp
@@ -163,9 +163,12 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
!inst->IsDebugInfo() && !inst->IsNonSemantic() &&
!spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction &&
opcode != spv::Op::OpCooperativeMatrixLengthNV &&
+ opcode != spv::Op::OpCooperativeMatrixLengthKHR &&
!(opcode == spv::Op::OpSpecConstantOp &&
- spv::Op(inst->word(3)) ==
- spv::Op::OpCooperativeMatrixLengthNV)) {
+ (spv::Op(inst->word(3)) ==
+ spv::Op::OpCooperativeMatrixLengthNV ||
+ spv::Op(inst->word(3)) ==
+ spv::Op::OpCooperativeMatrixLengthKHR))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Operand " << _.getIdName(operand_word)
<< " cannot be a type";
@@ -179,9 +182,12 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
opcode != spv::Op::OpLoopMerge &&
opcode != spv::Op::OpFunction &&
opcode != spv::Op::OpCooperativeMatrixLengthNV &&
+ opcode != spv::Op::OpCooperativeMatrixLengthKHR &&
!(opcode == spv::Op::OpSpecConstantOp &&
- spv::Op(inst->word(3)) ==
- spv::Op::OpCooperativeMatrixLengthNV)) {
+ (spv::Op(inst->word(3)) ==
+ spv::Op::OpCooperativeMatrixLengthNV ||
+ spv::Op(inst->word(3)) ==
+ spv::Op::OpCooperativeMatrixLengthKHR))) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "Operand " << _.getIdName(operand_word)
<< " requires a type";
diff --git a/third_party/SPIRV-Tools/source/val/validate_image.cpp b/third_party/SPIRV-Tools/source/val/validate_image.cpp
index 733556b1d..a1a76ea27 100644
--- a/third_party/SPIRV-Tools/source/val/validate_image.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_image.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Google Inc.
+// Copyright (c) 2017 Google Inc.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights
// reserved.
//
@@ -297,7 +297,6 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
spv::ImageOperandsMask::ConstOffsets |
spv::ImageOperandsMask::Offsets)) > 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << _.VkErrorID(4662)
<< "Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
"cannot be used together";
}
@@ -496,7 +495,7 @@ spv_result_t ValidateImageOperands(ValidationState_t& _,
}
uint64_t array_size = 0;
- if (!_.GetConstantValUint64(type_inst->word(3), &array_size)) {
+ if (!_.EvalConstantValUint64(type_inst->word(3), &array_size)) {
assert(0 && "Array type definition is corrupt");
}
@@ -694,16 +693,11 @@ spv_result_t ValidateImageReadWrite(ValidationState_t& _,
<< "storage image";
}
- if (info.multisampled == 1 &&
+ if (info.multisampled == 1 && info.arrayed == 1 && info.sampled == 2 &&
!_.HasCapability(spv::Capability::ImageMSArray)) {
-#if 0
- // TODO(atgoo@github.com) The description of this rule in the spec
- // is unclear and Glslang doesn't declare ImageMSArray. Need to clarify
- // and reenable.
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << "Capability ImageMSArray is required to access storage "
- << "image";
-#endif
+ << "Capability ImageMSArray is required to access storage "
+ << "image";
}
} else if (info.sampled != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -920,7 +914,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0";
+ << _.VkErrorID(6214)
+ << "Dim SubpassData requires Arrayed to be 0 in the Vulkan "
+ "environment";
+ }
+
+ if (info.dim == spv::Dim::Rect) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << _.VkErrorID(9638)
+ << "Dim must not be Rect in the Vulkan environment";
}
}
@@ -984,6 +986,14 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
case spv::Op::OpImageSparseGather:
case spv::Op::OpImageSparseDrefGather:
case spv::Op::OpCopyObject:
+ case spv::Op::OpImageSampleWeightedQCOM:
+ case spv::Op::OpImageBoxFilterQCOM:
+ case spv::Op::OpImageBlockMatchSSDQCOM:
+ case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
return true;
case spv::Op::OpStore:
if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
@@ -1087,6 +1097,18 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
}
}
}
+
+ const Instruction* ld_inst;
+ {
+ int t_idx = inst->GetOperandAs<int>(2);
+ ld_inst = _.FindDef(t_idx);
+ }
+
+ if (ld_inst->opcode() == spv::Op::OpLoad) {
+ int texture_id = ld_inst->GetOperandAs<int>(2); // variable to load
+ _.RegisterQCOMImageProcessingTextureConsumer(texture_id, ld_inst, inst);
+ }
+
return SPV_SUCCESS;
}
@@ -1108,7 +1130,10 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
const auto ptr_type = result_type->GetOperandAs<uint32_t>(2);
const auto ptr_opcode = _.GetIdOpcode(ptr_type);
if (ptr_opcode != spv::Op::OpTypeInt && ptr_opcode != spv::Op::OpTypeFloat &&
- ptr_opcode != spv::Op::OpTypeVoid) {
+ ptr_opcode != spv::Op::OpTypeVoid &&
+ !(ptr_opcode == spv::Op::OpTypeVector &&
+ _.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
+ _.IsFloat16Vector2Or4Type(ptr_type))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Result Type to be OpTypePointer whose Type operand "
"must be a scalar numerical type or OpTypeVoid";
@@ -1132,7 +1157,14 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
<< "Corrupt image type definition";
}
- if (info.sampled_type != ptr_type) {
+ if (info.sampled_type != ptr_type &&
+ !(_.HasCapability(spv::Capability::AtomicFloat16VectorNV) &&
+ _.IsFloat16Vector2Or4Type(ptr_type) &&
+ _.GetIdOpcode(info.sampled_type) == spv::Op::OpTypeFloat &&
+ ((_.GetDimension(ptr_type) == 2 &&
+ info.format == spv::ImageFormat::Rg16f) ||
+ (_.GetDimension(ptr_type) == 4 &&
+ info.format == spv::ImageFormat::Rgba16f)))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'Sampled Type' to be the same as the Type "
"pointed to by Result Type";
@@ -1190,7 +1222,7 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
if (info.multisampled == 0) {
uint64_t ms = 0;
- if (!_.GetConstantValUint64(inst->GetOperandAs<uint32_t>(4), &ms) ||
+ if (!_.EvalConstantValUint64(inst->GetOperandAs<uint32_t>(4), &ms) ||
ms != 0) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Sample for Image with MS 0 to be a valid <id> for "
@@ -1203,7 +1235,10 @@ spv_result_t ValidateImageTexelPointer(ValidationState_t& _,
(info.format != spv::ImageFormat::R64ui) &&
(info.format != spv::ImageFormat::R32f) &&
(info.format != spv::ImageFormat::R32i) &&
- (info.format != spv::ImageFormat::R32ui)) {
+ (info.format != spv::ImageFormat::R32ui) &&
+ !((info.format == spv::ImageFormat::Rg16f ||
+ info.format == spv::ImageFormat::Rgba16f) &&
+ _.HasCapability(spv::Capability::AtomicFloat16VectorNV))) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4658)
<< "Expected the Image Format in Image to be R64i, R64ui, R32f, "
@@ -2130,6 +2165,127 @@ spv_result_t ValidateImageSparseTexelsResident(ValidationState_t& _,
return SPV_SUCCESS;
}
+spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id,
+ spv::Decoration decor) {
+ const Instruction* si_inst = nullptr;
+ const Instruction* ld_inst = _.FindDef(id);
+ bool is_intf_obj = (ld_inst->opcode() == spv::Op::OpSampledImage);
+ if (is_intf_obj == true) {
+ si_inst = ld_inst;
+ int t_idx = si_inst->GetOperandAs<int>(2); // texture
+ ld_inst = _.FindDef(t_idx);
+ }
+ if (ld_inst->opcode() != spv::Op::OpLoad) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad";
+ }
+ int texture_id = ld_inst->GetOperandAs<int>(2); // variable to load
+ if (!_.HasDecoration(texture_id, decor)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+ << "Missing decoration " << _.SpvDecorationString(decor);
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateImageProcessing2QCOMWindowDecoration(ValidationState_t& _,
+ int id) {
+ const Instruction* ld_inst = _.FindDef(id);
+ bool is_intf_obj = (ld_inst->opcode() != spv::Op::OpSampledImage);
+ if (is_intf_obj == true) {
+ if (ld_inst->opcode() != spv::Op::OpLoad) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad";
+ }
+ int texture_id = ld_inst->GetOperandAs<int>(2); // variable to load
+ spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM;
+ if (!_.HasDecoration(texture_id, decor)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+ << "Missing decoration " << _.SpvDecorationString(decor);
+ }
+ decor = spv::Decoration::BlockMatchSamplerQCOM;
+ if (!_.HasDecoration(texture_id, decor)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+ << "Missing decoration " << _.SpvDecorationString(decor);
+ }
+ } else {
+ const Instruction* si_inst = ld_inst;
+ int t_idx = si_inst->GetOperandAs<int>(2); // texture
+ const Instruction* t_ld_inst = _.FindDef(t_idx);
+ if (t_ld_inst->opcode() != spv::Op::OpLoad) {
+ return _.diag(SPV_ERROR_INVALID_DATA, t_ld_inst)
+ << "Expect to see OpLoad";
+ }
+ int texture_id = t_ld_inst->GetOperandAs<int>(2); // variable to load
+ spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM;
+ if (!_.HasDecoration(texture_id, decor)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+ << "Missing decoration " << _.SpvDecorationString(decor);
+ }
+ int s_idx = si_inst->GetOperandAs<int>(3); // sampler
+ const Instruction* s_ld_inst = _.FindDef(s_idx);
+ if (s_ld_inst->opcode() != spv::Op::OpLoad) {
+ return _.diag(SPV_ERROR_INVALID_DATA, s_ld_inst)
+ << "Expect to see OpLoad";
+ }
+ int sampler_id = s_ld_inst->GetOperandAs<int>(2); // variable to load
+ decor = spv::Decoration::BlockMatchSamplerQCOM;
+ if (!_.HasDecoration(sampler_id, decor)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, ld_inst)
+ << "Missing decoration " << _.SpvDecorationString(decor);
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _,
+ const Instruction* inst) {
+ spv_result_t res = SPV_SUCCESS;
+ const spv::Op opcode = inst->opcode();
+ switch (opcode) {
+ case spv::Op::OpImageSampleWeightedQCOM: {
+ int wi_idx = inst->GetOperandAs<int>(4); // weight
+ res = ValidateImageProcessingQCOMDecoration(
+ _, wi_idx, spv::Decoration::WeightTextureQCOM);
+ break;
+ }
+ case spv::Op::OpImageBlockMatchSSDQCOM:
+ case spv::Op::OpImageBlockMatchSADQCOM: {
+ int tgt_idx = inst->GetOperandAs<int>(2); // target
+ res = ValidateImageProcessingQCOMDecoration(
+ _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
+ if (res != SPV_SUCCESS) break;
+ int ref_idx = inst->GetOperandAs<int>(4); // reference
+ res = ValidateImageProcessingQCOMDecoration(
+ _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
+ break;
+ }
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM: {
+ int tgt_idx = inst->GetOperandAs<int>(2); // target
+ res = ValidateImageProcessing2QCOMWindowDecoration(_, tgt_idx);
+ if (res != SPV_SUCCESS) break;
+ int ref_idx = inst->GetOperandAs<int>(4); // reference
+ res = ValidateImageProcessing2QCOMWindowDecoration(_, ref_idx);
+ break;
+ }
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM: {
+ int tgt_idx = inst->GetOperandAs<int>(2); // target
+ res = ValidateImageProcessingQCOMDecoration(
+ _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM);
+ if (res != SPV_SUCCESS) break;
+ int ref_idx = inst->GetOperandAs<int>(4); // reference
+ res = ValidateImageProcessingQCOMDecoration(
+ _, ref_idx, spv::Decoration::BlockMatchTextureQCOM);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return res;
+}
+
} // namespace
// Validates correctness of image instructions.
@@ -2249,10 +2405,113 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpImageSparseTexelsResident:
return ValidateImageSparseTexelsResident(_, inst);
+ case spv::Op::OpImageSampleWeightedQCOM:
+ case spv::Op::OpImageBoxFilterQCOM:
+ case spv::Op::OpImageBlockMatchSSDQCOM:
+ case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ return ValidateImageProcessingQCOM(_, inst);
+
+ default:
+ break;
+ }
+
+ return SPV_SUCCESS;
+}
+
+bool IsImageInstruction(const spv::Op opcode) {
+ switch (opcode) {
+ case spv::Op::OpImageSampleImplicitLod:
+ case spv::Op::OpImageSampleDrefImplicitLod:
+ case spv::Op::OpImageSampleProjImplicitLod:
+ case spv::Op::OpImageSampleProjDrefImplicitLod:
+ case spv::Op::OpImageSparseSampleImplicitLod:
+ case spv::Op::OpImageSparseSampleDrefImplicitLod:
+ case spv::Op::OpImageSparseSampleProjImplicitLod:
+ case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
+
+ case spv::Op::OpImageSampleExplicitLod:
+ case spv::Op::OpImageSampleDrefExplicitLod:
+ case spv::Op::OpImageSampleProjExplicitLod:
+ case spv::Op::OpImageSampleProjDrefExplicitLod:
+ case spv::Op::OpImageSparseSampleExplicitLod:
+ case spv::Op::OpImageSparseSampleDrefExplicitLod:
+ case spv::Op::OpImageSparseSampleProjExplicitLod:
+ case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
+
+ case spv::Op::OpImage:
+ case spv::Op::OpImageFetch:
+ case spv::Op::OpImageSparseFetch:
+ case spv::Op::OpImageGather:
+ case spv::Op::OpImageDrefGather:
+ case spv::Op::OpImageSparseGather:
+ case spv::Op::OpImageSparseDrefGather:
+ case spv::Op::OpImageRead:
+ case spv::Op::OpImageSparseRead:
+ case spv::Op::OpImageWrite:
+
+ case spv::Op::OpImageQueryFormat:
+ case spv::Op::OpImageQueryOrder:
+ case spv::Op::OpImageQuerySizeLod:
+ case spv::Op::OpImageQuerySize:
+ case spv::Op::OpImageQueryLod:
+ case spv::Op::OpImageQueryLevels:
+ case spv::Op::OpImageQuerySamples:
+
+ case spv::Op::OpImageSampleWeightedQCOM:
+ case spv::Op::OpImageBoxFilterQCOM:
+ case spv::Op::OpImageBlockMatchSSDQCOM:
+ case spv::Op::OpImageBlockMatchSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ return true;
default:
break;
}
+ return false;
+}
+spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _,
+ const Instruction* inst) {
+ const spv::Op opcode = inst->opcode();
+ if (!IsImageInstruction(opcode)) return SPV_SUCCESS;
+
+ switch (opcode) {
+ case spv::Op::OpImageSampleWeightedQCOM:
+ case spv::Op::OpImageBoxFilterQCOM:
+ case spv::Op::OpImageBlockMatchSSDQCOM:
+ case spv::Op::OpImageBlockMatchSADQCOM:
+ break;
+ case spv::Op::OpImageBlockMatchWindowSADQCOM:
+ case spv::Op::OpImageBlockMatchWindowSSDQCOM:
+ case spv::Op::OpImageBlockMatchGatherSADQCOM:
+ case spv::Op::OpImageBlockMatchGatherSSDQCOM:
+ break;
+ default:
+ for (size_t i = 0; i < inst->operands().size(); ++i) {
+ int id = inst->GetOperandAs<int>(i);
+ const Instruction* operand_inst = _.FindDef(id);
+ if (operand_inst == nullptr) continue;
+ if (operand_inst->opcode() == spv::Op::OpLoad) {
+ if (_.IsQCOMImageProcessingTextureConsumer(id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Illegal use of QCOM image processing decorated texture";
+ }
+ }
+ if (operand_inst->opcode() == spv::Op::OpSampledImage) {
+ if (_.IsQCOMImageProcessingTextureConsumer(id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Illegal use of QCOM image processing decorated texture";
+ }
+ }
+ }
+ break;
+ }
return SPV_SUCCESS;
}
diff --git a/third_party/SPIRV-Tools/source/val/validate_instruction.cpp b/third_party/SPIRV-Tools/source/val/validate_instruction.cpp
index fde6e52e5..5bc4d2cef 100644
--- a/third_party/SPIRV-Tools/source/val/validate_instruction.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_instruction.cpp
@@ -38,14 +38,14 @@ namespace {
std::string ToString(const CapabilitySet& capabilities,
const AssemblyGrammar& grammar) {
std::stringstream ss;
- capabilities.ForEach([&grammar, &ss](spv::Capability cap) {
+ for (auto capability : capabilities) {
spv_operand_desc desc;
if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
- uint32_t(cap), &desc))
+ uint32_t(capability), &desc))
ss << desc->name << " ";
else
- ss << uint32_t(cap) << " ";
- });
+ ss << uint32_t(capability) << " ";
+ }
return ss.str();
}
@@ -178,10 +178,11 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state,
// Vulkan API requires more capabilities on rounding mode.
if (spvIsVulkanEnv(state.context()->target_env)) {
- enabling_capabilities.Add(spv::Capability::StorageUniformBufferBlock16);
- enabling_capabilities.Add(spv::Capability::StorageUniform16);
- enabling_capabilities.Add(spv::Capability::StoragePushConstant16);
- enabling_capabilities.Add(spv::Capability::StorageInputOutput16);
+ enabling_capabilities.insert(
+ spv::Capability::StorageUniformBufferBlock16);
+ enabling_capabilities.insert(spv::Capability::StorageUniform16);
+ enabling_capabilities.insert(spv::Capability::StoragePushConstant16);
+ enabling_capabilities.insert(spv::Capability::StorageInputOutput16);
}
} else {
enabling_capabilities = state.grammar().filterCapsAgainstTargetEnv(
@@ -195,7 +196,7 @@ spv_result_t CheckRequiredCapabilities(ValidationState_t& state,
if (inst->opcode() != spv::Op::OpCapability) {
const bool enabled_by_cap =
state.HasAnyOfCapabilities(enabling_capabilities);
- if (!enabling_capabilities.IsEmpty() && !enabled_by_cap) {
+ if (!enabling_capabilities.empty() && !enabled_by_cap) {
return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
<< "Operand " << which_operand << " of "
<< spvOpcodeString(inst->opcode())
@@ -303,7 +304,7 @@ spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) {
}
ExtensionSet exts(inst_desc->numExtensions, inst_desc->extensions);
- if (exts.IsEmpty()) {
+ if (exts.empty()) {
// If no extensions can enable this instruction, then emit error
// messages only concerning core SPIR-V versions if errors happen.
if (min_version == ~0u) {
@@ -469,7 +470,8 @@ spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) {
}
_.set_addressing_model(inst->GetOperandAs<spv::AddressingModel>(0));
_.set_memory_model(inst->GetOperandAs<spv::MemoryModel>(1));
- } else if (opcode == spv::Op::OpExecutionMode) {
+ } else if (opcode == spv::Op::OpExecutionMode ||
+ opcode == spv::Op::OpExecutionModeId) {
const uint32_t entry_point = inst->word(1);
_.RegisterExecutionModeForEntryPoint(entry_point,
spv::ExecutionMode(inst->word(2)));
diff --git a/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp b/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
index 35666984d..ace548aa1 100644
--- a/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_interfaces.cpp
@@ -173,8 +173,19 @@ spv_result_t NumConsumedLocations(ValidationState_t& _, const Instruction* type,
}
break;
}
+ case spv::Op::OpTypePointer: {
+ if (_.addressing_model() ==
+ spv::AddressingModel::PhysicalStorageBuffer64 &&
+ type->GetOperandAs<spv::StorageClass>(1) ==
+ spv::StorageClass::PhysicalStorageBuffer) {
+ *num_locations = 1;
+ break;
+ }
+ [[fallthrough]];
+ }
default:
- break;
+ return _.diag(SPV_ERROR_INVALID_DATA, type)
+ << "Invalid type to assign a location";
}
return SPV_SUCCESS;
@@ -206,6 +217,14 @@ uint32_t NumConsumedComponents(ValidationState_t& _, const Instruction* type) {
// Skip the array.
return NumConsumedComponents(_,
_.FindDef(type->GetOperandAs<uint32_t>(1)));
+ case spv::Op::OpTypePointer:
+ if (_.addressing_model() ==
+ spv::AddressingModel::PhysicalStorageBuffer64 &&
+ type->GetOperandAs<spv::StorageClass>(1) ==
+ spv::StorageClass::PhysicalStorageBuffer) {
+ return 2;
+ }
+ break;
default:
// This is an error that is validated elsewhere.
break;
@@ -235,37 +254,24 @@ spv_result_t GetLocationsForVariable(
// equal. Also track Patch and PerTaskNV decorations.
bool has_location = false;
uint32_t location = 0;
- bool has_component = false;
uint32_t component = 0;
bool has_index = false;
uint32_t index = 0;
bool has_patch = false;
bool has_per_task_nv = false;
bool has_per_vertex_khr = false;
+ // Duplicate Location, Component, Index are checked elsewhere.
for (auto& dec : _.id_decorations(variable->id())) {
if (dec.dec_type() == spv::Decoration::Location) {
- if (has_location && dec.params()[0] != location) {
- return _.diag(SPV_ERROR_INVALID_DATA, variable)
- << "Variable has conflicting location decorations";
- }
has_location = true;
location = dec.params()[0];
} else if (dec.dec_type() == spv::Decoration::Component) {
- if (has_component && dec.params()[0] != component) {
- return _.diag(SPV_ERROR_INVALID_DATA, variable)
- << "Variable has conflicting component decorations";
- }
- has_component = true;
component = dec.params()[0];
} else if (dec.dec_type() == spv::Decoration::Index) {
if (!is_output || !is_fragment) {
return _.diag(SPV_ERROR_INVALID_DATA, variable)
<< "Index can only be applied to Fragment output variables";
}
- if (has_index && dec.params()[0] != index) {
- return _.diag(SPV_ERROR_INVALID_DATA, variable)
- << "Variable has conflicting index decorations";
- }
has_index = true;
index = dec.params()[0];
} else if (dec.dec_type() == spv::Decoration::BuiltIn) {
@@ -363,12 +369,12 @@ spv_result_t GetLocationsForVariable(
sub_type = _.FindDef(sub_type_id);
}
- for (uint32_t array_idx = 0; array_idx < array_size; ++array_idx) {
- uint32_t num_locations = 0;
- if (auto error = NumConsumedLocations(_, sub_type, &num_locations))
- return error;
+ uint32_t num_locations = 0;
+ if (auto error = NumConsumedLocations(_, sub_type, &num_locations))
+ return error;
+ uint32_t num_components = NumConsumedComponents(_, sub_type);
- uint32_t num_components = NumConsumedComponents(_, sub_type);
+ for (uint32_t array_idx = 0; array_idx < array_size; ++array_idx) {
uint32_t array_location = location + (num_locations * array_idx);
uint32_t start = array_location * 4;
if (kMaxLocations <= start) {
@@ -388,6 +394,7 @@ spv_result_t GetLocationsForVariable(
for (uint32_t i = start; i < end; ++i) {
if (!locs->insert(i).second) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721))
<< "Entry-point has conflicting " << storage_class
<< " location assignment at location " << i / 4
<< ", component " << i % 4;
@@ -459,6 +466,7 @@ spv_result_t GetLocationsForVariable(
uint32_t check = 4 * l + c;
if (!locations->insert(check).second) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721))
<< "Entry-point has conflicting " << storage_class
<< " location assignment at location " << l
<< ", component " << c;
@@ -476,6 +484,7 @@ spv_result_t GetLocationsForVariable(
for (uint32_t l = start; l < end; ++l) {
if (!locations->insert(l).second) {
return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << (is_output ? _.VkErrorID(8722) : _.VkErrorID(8721))
<< "Entry-point has conflicting " << storage_class
<< " location assignment at location " << l / 4
<< ", component " << l % 4;
@@ -536,6 +545,64 @@ spv_result_t ValidateLocations(ValidationState_t& _,
return SPV_SUCCESS;
}
+spv_result_t ValidateStorageClass(ValidationState_t& _,
+ const Instruction* entry_point) {
+ bool has_push_constant = false;
+ bool has_ray_payload = false;
+ bool has_hit_attribute = false;
+ bool has_callable_data = false;
+ for (uint32_t i = 3; i < entry_point->operands().size(); ++i) {
+ auto interface_id = entry_point->GetOperandAs<uint32_t>(i);
+ auto interface_var = _.FindDef(interface_id);
+ auto storage_class = interface_var->GetOperandAs<spv::StorageClass>(2);
+ switch (storage_class) {
+ case spv::StorageClass::PushConstant: {
+ if (has_push_constant) {
+ return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << _.VkErrorID(6673)
+ << "Entry-point has more than one variable with the "
+ "PushConstant storage class in the interface";
+ }
+ has_push_constant = true;
+ break;
+ }
+ case spv::StorageClass::IncomingRayPayloadKHR: {
+ if (has_ray_payload) {
+ return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << _.VkErrorID(4700)
+ << "Entry-point has more than one variable with the "
+ "IncomingRayPayloadKHR storage class in the interface";
+ }
+ has_ray_payload = true;
+ break;
+ }
+ case spv::StorageClass::HitAttributeKHR: {
+ if (has_hit_attribute) {
+ return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << _.VkErrorID(4702)
+ << "Entry-point has more than one variable with the "
+ "HitAttributeKHR storage class in the interface";
+ }
+ has_hit_attribute = true;
+ break;
+ }
+ case spv::StorageClass::IncomingCallableDataKHR: {
+ if (has_callable_data) {
+ return _.diag(SPV_ERROR_INVALID_DATA, entry_point)
+ << _.VkErrorID(4706)
+ << "Entry-point has more than one variable with the "
+ "IncomingCallableDataKHR storage class in the interface";
+ }
+ has_callable_data = true;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ return SPV_SUCCESS;
+}
+
} // namespace
spv_result_t ValidateInterfaces(ValidationState_t& _) {
@@ -554,6 +621,9 @@ spv_result_t ValidateInterfaces(ValidationState_t& _) {
if (auto error = ValidateLocations(_, &inst)) {
return error;
}
+ if (auto error = ValidateStorageClass(_, &inst)) {
+ return error;
+ }
}
if (inst.opcode() == spv::Op::OpTypeVoid) break;
}
diff --git a/third_party/SPIRV-Tools/source/val/validate_memory.cpp b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
index 5f7358c68..2d6715f42 100644
--- a/third_party/SPIRV-Tools/source/val/validate_memory.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_memory.cpp
@@ -204,6 +204,7 @@ bool ContainsCooperativeMatrix(ValidationState_t& _,
switch (storage->opcode()) {
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
return true;
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray:
@@ -232,6 +233,7 @@ std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
spv::StorageClass src_sc = spv::StorageClass::Max;
switch (inst->opcode()) {
case spv::Op::OpCooperativeMatrixLoadNV:
+ case spv::Op::OpCooperativeMatrixLoadKHR:
case spv::Op::OpLoad: {
auto load_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(2));
auto load_pointer_type = _.FindDef(load_pointer->type_id());
@@ -239,6 +241,7 @@ std::pair<spv::StorageClass, spv::StorageClass> GetStorageClass(
break;
}
case spv::Op::OpCooperativeMatrixStoreNV:
+ case spv::Op::OpCooperativeMatrixStoreKHR:
case spv::Op::OpStore: {
auto store_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
auto store_pointer_type = _.FindDef(store_pointer->type_id());
@@ -326,7 +329,8 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst,
const uint32_t mask = inst->GetOperandAs<uint32_t>(index);
if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
if (inst->opcode() == spv::Op::OpLoad ||
- inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) {
+ inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV ||
+ inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "MakePointerAvailableKHR cannot be used with OpLoad.";
}
@@ -442,6 +446,7 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
storage_class != spv::StorageClass::CrossWorkgroup &&
storage_class != spv::StorageClass::Private &&
storage_class != spv::StorageClass::Function &&
+ storage_class != spv::StorageClass::UniformConstant &&
storage_class != spv::StorageClass::RayPayloadKHR &&
storage_class != spv::StorageClass::IncomingRayPayloadKHR &&
storage_class != spv::StorageClass::HitAttributeKHR &&
@@ -475,8 +480,8 @@ spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
"can only be used with non-externally visible shader Storage "
"Classes: Workgroup, CrossWorkgroup, Private, Function, "
"Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, "
- "HitAttributeKHR, CallableDataKHR, or "
- "IncomingCallableDataKHR";
+ "HitAttributeKHR, CallableDataKHR, "
+ "IncomingCallableDataKHR, or UniformConstant";
}
}
}
@@ -961,6 +966,8 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
}
}
+ _.RegisterQCOMImageProcessingTextureConsumer(pointer_id, inst, nullptr);
+
return SPV_SUCCESS;
}
@@ -1356,6 +1363,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray: {
// In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV,
@@ -1366,33 +1374,30 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
case spv::Op::OpTypeStruct: {
// In case of structures, there is an additional constraint on the
// index: the index must be an OpConstant.
- if (spv::Op::OpConstant != cur_word_instr->opcode()) {
+ int64_t cur_index;
+ if (!_.EvalConstantValInt64(cur_word, &cur_index)) {
return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
<< "The <id> passed to " << instr_name
<< " to index into a "
"structure must be an OpConstant.";
}
- // Get the index value from the OpConstant (word 3 of OpConstant).
- // OpConstant could be a signed integer. But it's okay to treat it as
- // unsigned because a negative constant int would never be seen as
- // correct as a struct offset, since structs can't have more than 2
- // billion members.
- const uint32_t cur_index = cur_word_instr->word(3);
+
// The index points to the struct member we want, therefore, the index
// should be less than the number of struct members.
- const uint32_t num_struct_members =
- static_cast<uint32_t>(type_pointee->words().size() - 2);
- if (cur_index >= num_struct_members) {
+ const int64_t num_struct_members =
+ static_cast<int64_t>(type_pointee->words().size() - 2);
+ if (cur_index >= num_struct_members || cur_index < 0) {
return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
<< "Index is out of bounds: " << instr_name
- << " can not find index " << cur_index
+ << " cannot find index " << cur_index
<< " into the structure <id> "
<< _.getIdName(type_pointee->id()) << ". This structure has "
<< num_struct_members << " members. Largest valid index is "
<< num_struct_members - 1 << ".";
}
// Struct members IDs start at word 2 of OpTypeStruct.
- auto structMemberId = type_pointee->word(cur_index + 2);
+ const size_t word_index = static_cast<size_t>(cur_index) + 2;
+ auto structMemberId = type_pointee->word(word_index);
type_pointee = _.FindDef(structMemberId);
break;
}
@@ -1405,7 +1410,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
}
}
}
- // At this point, we have fully walked down from the base using the indeces.
+ // At this point, we have fully walked down from the base using the indices.
// The type being pointed to should be the same as the result type.
if (type_pointee->id() != result_type_pointee->id()) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
@@ -1422,6 +1427,126 @@ spv_result_t ValidateAccessChain(ValidationState_t& _,
return SPV_SUCCESS;
}
+spv_result_t ValidateRawAccessChain(ValidationState_t& _,
+ const Instruction* inst) {
+ std::string instr_name = "Op" + std::string(spvOpcodeString(inst->opcode()));
+
+ // The result type must be OpTypePointer.
+ const auto result_type = _.FindDef(inst->type_id());
+ if (spv::Op::OpTypePointer != result_type->opcode()) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The Result Type of " << instr_name << " <id> "
+ << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
+ << spvOpcodeString(result_type->opcode()) << '.';
+ }
+
+ // The pointed storage class must be valid.
+ const auto storage_class = result_type->GetOperandAs<spv::StorageClass>(1);
+ if (storage_class != spv::StorageClass::StorageBuffer &&
+ storage_class != spv::StorageClass::PhysicalStorageBuffer &&
+ storage_class != spv::StorageClass::Uniform) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The Result Type of " << instr_name << " <id> "
+ << _.getIdName(inst->id())
+ << " must point to a storage class of "
+ "StorageBuffer, PhysicalStorageBuffer, or Uniform.";
+ }
+
+ // The pointed type must not be one in the list below.
+ const auto result_type_pointee =
+ _.FindDef(result_type->GetOperandAs<uint32_t>(2));
+ if (result_type_pointee->opcode() == spv::Op::OpTypeArray ||
+ result_type_pointee->opcode() == spv::Op::OpTypeMatrix ||
+ result_type_pointee->opcode() == spv::Op::OpTypeStruct) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The Result Type of " << instr_name << " <id> "
+ << _.getIdName(inst->id())
+ << " must not point to "
+ "OpTypeArray, OpTypeMatrix, or OpTypeStruct.";
+ }
+
+ // Validate Stride is a OpConstant.
+ const auto stride = _.FindDef(inst->GetOperandAs<uint32_t>(3));
+ if (stride->opcode() != spv::Op::OpConstant) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The Stride of " << instr_name << " <id> "
+ << _.getIdName(inst->id()) << " must be OpConstant. Found Op"
+ << spvOpcodeString(stride->opcode()) << '.';
+ }
+ // Stride type must be OpTypeInt
+ const auto stride_type = _.FindDef(stride->type_id());
+ if (stride_type->opcode() != spv::Op::OpTypeInt) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The type of Stride of " << instr_name << " <id> "
+ << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op"
+ << spvOpcodeString(stride_type->opcode()) << '.';
+ }
+
+ // Index and Offset type must be OpTypeInt with a width of 32
+ const auto ValidateType = [&](const char* name,
+ int operandIndex) -> spv_result_t {
+ const auto value = _.FindDef(inst->GetOperandAs<uint32_t>(operandIndex));
+ const auto value_type = _.FindDef(value->type_id());
+ if (value_type->opcode() != spv::Op::OpTypeInt) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The type of " << name << " of " << instr_name << " <id> "
+ << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op"
+ << spvOpcodeString(value_type->opcode()) << '.';
+ }
+ const auto width = value_type->GetOperandAs<uint32_t>(1);
+ if (width != 32) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The integer width of " << name << " of " << instr_name
+ << " <id> " << _.getIdName(inst->id()) << " must be 32. Found "
+ << width << '.';
+ }
+ return SPV_SUCCESS;
+ };
+ spv_result_t result;
+ result = ValidateType("Index", 4);
+ if (result != SPV_SUCCESS) {
+ return result;
+ }
+ result = ValidateType("Offset", 5);
+ if (result != SPV_SUCCESS) {
+ return result;
+ }
+
+ uint32_t access_operands = 0;
+ if (inst->operands().size() >= 7) {
+ access_operands = inst->GetOperandAs<uint32_t>(6);
+ }
+ if (access_operands &
+ uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
+ uint64_t stride_value = 0;
+ if (_.EvalConstantValUint64(stride->id(), &stride_value) &&
+ stride_value == 0) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Stride must not be zero when per-element robustness is used.";
+ }
+ }
+ if (access_operands &
+ uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) ||
+ access_operands &
+ uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
+ if (storage_class == spv::StorageClass::PhysicalStorageBuffer) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Storage class cannot be PhysicalStorageBuffer when "
+ "raw access chain robustness is used.";
+ }
+ }
+ if (access_operands &
+ uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) &&
+ access_operands &
+ uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Per-component robustness and per-element robustness are "
+ "mutually exclusive.";
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t ValidatePtrAccessChain(ValidationState_t& _,
const Instruction* inst) {
if (_.addressing_model() == spv::AddressingModel::Logical) {
@@ -1553,9 +1678,15 @@ spv_result_t ValidateCooperativeMatrixLengthNV(ValidationState_t& state,
<< " must be OpTypeInt with width 32 and signedness 0.";
}
+ bool isKhr = inst->opcode() == spv::Op::OpCooperativeMatrixLengthKHR;
auto type_id = inst->GetOperandAs<uint32_t>(2);
auto type = state.FindDef(type_id);
- if (type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
+ if (isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
+ return state.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The type in " << instr_name << " <id> "
+ << state.getIdName(type_id)
+ << " must be OpTypeCooperativeMatrixKHR.";
+ } else if (!isKhr && type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
return state.diag(SPV_ERROR_INVALID_ID, inst)
<< "The type in " << instr_name << " <id> "
<< state.getIdName(type_id) << " must be OpTypeCooperativeMatrixNV.";
@@ -1667,6 +1798,113 @@ spv_result_t ValidateCooperativeMatrixLoadStoreNV(ValidationState_t& _,
return SPV_SUCCESS;
}
+spv_result_t ValidateCooperativeMatrixLoadStoreKHR(ValidationState_t& _,
+ const Instruction* inst) {
+ uint32_t type_id;
+ const char* opname;
+ if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
+ type_id = inst->type_id();
+ opname = "spv::Op::OpCooperativeMatrixLoadKHR";
+ } else {
+ // get Object operand's type
+ type_id = _.FindDef(inst->GetOperandAs<uint32_t>(1))->type_id();
+ opname = "spv::Op::OpCooperativeMatrixStoreKHR";
+ }
+
+ auto matrix_type = _.FindDef(type_id);
+
+ if (matrix_type->opcode() != spv::Op::OpTypeCooperativeMatrixKHR) {
+ if (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "spv::Op::OpCooperativeMatrixLoadKHR Result Type <id> "
+ << _.getIdName(type_id) << " is not a cooperative matrix type.";
+ } else {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "spv::Op::OpCooperativeMatrixStoreKHR Object type <id> "
+ << _.getIdName(type_id) << " is not a cooperative matrix type.";
+ }
+ }
+
+ const auto pointer_index =
+ (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 2u : 0u;
+ const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
+ const auto pointer = _.FindDef(pointer_id);
+ if (!pointer ||
+ ((_.addressing_model() == spv::AddressingModel::Logical) &&
+ ((!_.features().variable_pointers &&
+ !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
+ (_.features().variable_pointers &&
+ !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << opname << " Pointer <id> " << _.getIdName(pointer_id)
+ << " is not a logical pointer.";
+ }
+
+ const auto pointer_type_id = pointer->type_id();
+ const auto pointer_type = _.FindDef(pointer_type_id);
+ if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << opname << " type for pointer <id> " << _.getIdName(pointer_id)
+ << " is not a pointer type.";
+ }
+
+ const auto storage_class_index = 1u;
+ const auto storage_class =
+ pointer_type->GetOperandAs<spv::StorageClass>(storage_class_index);
+
+ if (storage_class != spv::StorageClass::Workgroup &&
+ storage_class != spv::StorageClass::StorageBuffer &&
+ storage_class != spv::StorageClass::PhysicalStorageBuffer) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << _.VkErrorID(8973) << opname
+ << " storage class for pointer type <id> "
+ << _.getIdName(pointer_type_id)
+ << " is not Workgroup, StorageBuffer, or PhysicalStorageBuffer.";
+ }
+
+ const auto pointee_id = pointer_type->GetOperandAs<uint32_t>(2);
+ const auto pointee_type = _.FindDef(pointee_id);
+ if (!pointee_type || !(_.IsIntScalarOrVectorType(pointee_id) ||
+ _.IsFloatScalarOrVectorType(pointee_id))) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << opname << " Pointer <id> " << _.getIdName(pointer->id())
+ << "s Type must be a scalar or vector type.";
+ }
+
+ const auto layout_index =
+ (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 3u : 2u;
+ const auto colmajor_id = inst->GetOperandAs<uint32_t>(layout_index);
+ const auto colmajor = _.FindDef(colmajor_id);
+ if (!colmajor || !_.IsIntScalarType(colmajor->type_id()) ||
+ !(spvOpcodeIsConstant(colmajor->opcode()) ||
+ spvOpcodeIsSpecConstant(colmajor->opcode()))) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "MemoryLayout operand <id> " << _.getIdName(colmajor_id)
+ << " must be a 32-bit integer constant instruction.";
+ }
+
+ const auto stride_index =
+ (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 4u : 3u;
+ if (inst->operands().size() > stride_index) {
+ const auto stride_id = inst->GetOperandAs<uint32_t>(stride_index);
+ const auto stride = _.FindDef(stride_id);
+ if (!stride || !_.IsIntScalarType(stride->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Stride operand <id> " << _.getIdName(stride_id)
+ << " must be a scalar integer type.";
+ }
+ }
+
+ const auto memory_access_index =
+ (inst->opcode() == spv::Op::OpCooperativeMatrixLoadKHR) ? 5u : 4u;
+ if (inst->operands().size() > memory_access_index) {
+ if (auto error = CheckMemoryAccess(_, inst, memory_access_index))
+ return error;
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t ValidatePtrComparison(ValidationState_t& _,
const Instruction* inst) {
if (_.addressing_model() == spv::AddressingModel::Logical &&
@@ -1748,6 +1986,9 @@ spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) {
case spv::Op::OpInBoundsPtrAccessChain:
if (auto error = ValidateAccessChain(_, inst)) return error;
break;
+ case spv::Op::OpRawAccessChainNV:
+ if (auto error = ValidateRawAccessChain(_, inst)) return error;
+ break;
case spv::Op::OpArrayLength:
if (auto error = ValidateArrayLength(_, inst)) return error;
break;
@@ -1756,9 +1997,15 @@ spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) {
if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst))
return error;
break;
+ case spv::Op::OpCooperativeMatrixLengthKHR:
case spv::Op::OpCooperativeMatrixLengthNV:
if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error;
break;
+ case spv::Op::OpCooperativeMatrixLoadKHR:
+ case spv::Op::OpCooperativeMatrixStoreKHR:
+ if (auto error = ValidateCooperativeMatrixLoadStoreKHR(_, inst))
+ return error;
+ break;
case spv::Op::OpPtrEqual:
case spv::Op::OpPtrNotEqual:
case spv::Op::OpPtrDiff:
diff --git a/third_party/SPIRV-Tools/source/val/validate_memory_semantics.cpp b/third_party/SPIRV-Tools/source/val/validate_memory_semantics.cpp
index c4f22a611..dab7b5a19 100644
--- a/third_party/SPIRV-Tools/source/val/validate_memory_semantics.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_memory_semantics.cpp
@@ -203,15 +203,12 @@ spv_result_t ValidateMemorySemantics(ValidationState_t& _,
"storage class";
}
-#if 0
- // TODO(atgoo@github.com): this check fails Vulkan CTS, reenable once fixed.
if (opcode == spv::Op::OpControlBarrier && value && !includes_storage_class) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << spvOpcodeString(opcode)
+ << _.VkErrorID(4650) << spvOpcodeString(opcode)
<< ": expected Memory Semantics to include a Vulkan-supported "
"storage class if Memory Semantics is not None";
}
-#endif
}
if (opcode == spv::Op::OpAtomicFlagClear &&
diff --git a/third_party/SPIRV-Tools/source/val/validate_mode_setting.cpp b/third_party/SPIRV-Tools/source/val/validate_mode_setting.cpp
index d757d4f82..8502fda53 100644
--- a/third_party/SPIRV-Tools/source/val/validate_mode_setting.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_mode_setting.cpp
@@ -340,29 +340,93 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
const auto mode = inst->GetOperandAs<spv::ExecutionMode>(1);
if (inst->opcode() == spv::Op::OpExecutionModeId) {
+ bool valid_mode = false;
+ switch (mode) {
+ case spv::ExecutionMode::SubgroupsPerWorkgroupId:
+ case spv::ExecutionMode::LocalSizeHintId:
+ case spv::ExecutionMode::LocalSizeId:
+ case spv::ExecutionMode::FPFastMathDefault:
+ case spv::ExecutionMode::MaximumRegistersIdINTEL:
+ valid_mode = true;
+ break;
+ default:
+ valid_mode = false;
+ break;
+ }
+ if (!valid_mode) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "OpExecutionModeId is only valid when the Mode operand is an "
+ "execution mode that takes Extra Operands that are id "
+ "operands.";
+ }
+
size_t operand_count = inst->operands().size();
for (size_t i = 2; i < operand_count; ++i) {
- const auto operand_id = inst->GetOperandAs<uint32_t>(2);
+ const auto operand_id = inst->GetOperandAs<uint32_t>(i);
const auto* operand_inst = _.FindDef(operand_id);
- if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId ||
- mode == spv::ExecutionMode::LocalSizeHintId ||
- mode == spv::ExecutionMode::LocalSizeId) {
- if (!spvOpcodeIsConstant(operand_inst->opcode())) {
- return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "For OpExecutionModeId all Extra Operand ids must be "
- "constant "
- "instructions.";
- }
- } else {
- return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpExecutionModeId is only valid when the Mode operand is an "
- "execution mode that takes Extra Operands that are id "
- "operands.";
+ switch (mode) {
+ case spv::ExecutionMode::SubgroupsPerWorkgroupId:
+ case spv::ExecutionMode::LocalSizeHintId:
+ case spv::ExecutionMode::LocalSizeId:
+ if (!spvOpcodeIsConstant(operand_inst->opcode())) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "For OpExecutionModeId all Extra Operand ids must be "
+ "constant instructions.";
+ }
+ break;
+ case spv::ExecutionMode::FPFastMathDefault:
+ if (i == 2) {
+ if (!_.IsFloatScalarType(operand_id)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The Target Type operand must be a floating-point "
+ "scalar type";
+ }
+ } else {
+ bool is_int32 = false;
+ bool is_const = false;
+ uint32_t value = 0;
+ std::tie(is_int32, is_const, value) =
+ _.EvalInt32IfConst(operand_id);
+ if (is_int32 && is_const) {
+ // Valid values include up to 0x00040000 (AllowTransform).
+ uint32_t invalid_mask = 0xfff80000;
+ if ((invalid_mask & value) != 0) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The Fast Math Default operand is an invalid bitmask "
+ "value";
+ }
+ if (value &
+ static_cast<uint32_t>(spv::FPFastMathModeMask::Fast)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The Fast Math Default operand must not include Fast";
+ }
+ const auto reassoc_contract =
+ spv::FPFastMathModeMask::AllowContract |
+ spv::FPFastMathModeMask::AllowReassoc;
+ if ((value & static_cast<uint32_t>(
+ spv::FPFastMathModeMask::AllowTransform)) != 0 &&
+ ((value & static_cast<uint32_t>(reassoc_contract)) !=
+ static_cast<uint32_t>(reassoc_contract))) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The Fast Math Default operand must include "
+ "AllowContract and AllowReassoc when AllowTransform "
+ "is specified";
+ }
+ } else {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "The Fast Math Default operand must be a "
+ "non-specialization constant";
+ }
+ }
+ break;
+ default:
+ break;
}
}
} else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId ||
mode == spv::ExecutionMode::LocalSizeHintId ||
- mode == spv::ExecutionMode::LocalSizeId) {
+ mode == spv::ExecutionMode::LocalSizeId ||
+ mode == spv::ExecutionMode::FPFastMathDefault) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "OpExecutionMode is only valid when the Mode operand is an "
"execution mode that takes no Extra Operands, or takes Extra "
@@ -494,6 +558,17 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
"model.";
}
break;
+ case spv::ExecutionMode::QuadDerivativesKHR:
+ if (!std::all_of(models->begin(), models->end(),
+ [](const spv::ExecutionModel& model) {
+ return (model == spv::ExecutionModel::Fragment ||
+ model == spv::ExecutionModel::GLCompute);
+ })) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Execution mode can only be used with the Fragment or "
+ "GLCompute execution model.";
+ }
+ break;
case spv::ExecutionMode::PixelCenterInteger:
case spv::ExecutionMode::OriginUpperLeft:
case spv::ExecutionMode::OriginLowerLeft:
@@ -518,6 +593,7 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
case spv::ExecutionMode::StencilRefUnchangedBackAMD:
case spv::ExecutionMode::StencilRefGreaterBackAMD:
case spv::ExecutionMode::StencilRefLessBackAMD:
+ case spv::ExecutionMode::RequireFullQuadsKHR:
if (!std::all_of(models->begin(), models->end(),
[](const spv::ExecutionModel& model) {
return model == spv::ExecutionModel::Fragment;
@@ -579,6 +655,20 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
break;
}
+ if (mode == spv::ExecutionMode::FPFastMathDefault) {
+ const auto* modes = _.GetExecutionModes(entry_point_id);
+ if (modes && modes->count(spv::ExecutionMode::ContractionOff)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "FPFastMathDefault and ContractionOff execution modes cannot "
+ "be applied to the same entry point";
+ }
+ if (modes && modes->count(spv::ExecutionMode::SignedZeroInfNanPreserve)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "FPFastMathDefault and SignedZeroInfNanPreserve execution "
+ "modes cannot be applied to the same entry point";
+ }
+ }
+
if (spvIsVulkanEnv(_.context()->target_env)) {
if (mode == spv::ExecutionMode::OriginLowerLeft) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -634,8 +724,91 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _,
return SPV_SUCCESS;
}
+bool PerEntryExecutionMode(spv::ExecutionMode mode) {
+ switch (mode) {
+ // These execution modes can be specified multiple times per entry point.
+ case spv::ExecutionMode::DenormPreserve:
+ case spv::ExecutionMode::DenormFlushToZero:
+ case spv::ExecutionMode::SignedZeroInfNanPreserve:
+ case spv::ExecutionMode::RoundingModeRTE:
+ case spv::ExecutionMode::RoundingModeRTZ:
+ case spv::ExecutionMode::FPFastMathDefault:
+ case spv::ExecutionMode::RoundingModeRTPINTEL:
+ case spv::ExecutionMode::RoundingModeRTNINTEL:
+ case spv::ExecutionMode::FloatingPointModeALTINTEL:
+ case spv::ExecutionMode::FloatingPointModeIEEEINTEL:
+ return false;
+ default:
+ return true;
+ }
+}
+
} // namespace
+spv_result_t ValidateFloatControls2(ValidationState_t& _) {
+ std::unordered_set<uint32_t> fp_fast_math_default_entry_points;
+ for (auto entry_point : _.entry_points()) {
+ const auto* exec_modes = _.GetExecutionModes(entry_point);
+ if (exec_modes &&
+ exec_modes->count(spv::ExecutionMode::FPFastMathDefault)) {
+ fp_fast_math_default_entry_points.insert(entry_point);
+ }
+ }
+
+ std::vector<std::pair<const Instruction*, spv::Decoration>> worklist;
+ for (const auto& inst : _.ordered_instructions()) {
+ if (inst.opcode() != spv::Op::OpDecorate) {
+ continue;
+ }
+
+ const auto decoration = inst.GetOperandAs<spv::Decoration>(1);
+ const auto target_id = inst.GetOperandAs<uint32_t>(0);
+ const auto target = _.FindDef(target_id);
+ if (decoration == spv::Decoration::NoContraction) {
+ worklist.push_back(std::make_pair(target, decoration));
+ } else if (decoration == spv::Decoration::FPFastMathMode) {
+ auto mask = inst.GetOperandAs<spv::FPFastMathModeMask>(2);
+ if ((mask & spv::FPFastMathModeMask::Fast) !=
+ spv::FPFastMathModeMask::MaskNone) {
+ worklist.push_back(std::make_pair(target, decoration));
+ }
+ }
+ }
+
+ std::unordered_set<const Instruction*> visited;
+ while (!worklist.empty()) {
+ const auto inst = worklist.back().first;
+ const auto decoration = worklist.back().second;
+ worklist.pop_back();
+
+ if (!visited.insert(inst).second) {
+ continue;
+ }
+
+ const auto function = inst->function();
+ if (function) {
+ const auto& entry_points = _.FunctionEntryPoints(function->id());
+ for (auto entry_point : entry_points) {
+ if (fp_fast_math_default_entry_points.count(entry_point)) {
+ const std::string dec = decoration == spv::Decoration::NoContraction
+ ? "NoContraction"
+ : "FPFastMathMode Fast";
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << dec
+ << " cannot be used by an entry point with the "
+ "FPFastMathDefault execution mode";
+ }
+ }
+ } else {
+ for (const auto& pair : inst->uses()) {
+ worklist.push_back(std::make_pair(pair.first, decoration));
+ }
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) {
switch (inst->opcode()) {
case spv::Op::OpEntryPoint:
@@ -654,5 +827,52 @@ spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) {
return SPV_SUCCESS;
}
+spv_result_t ValidateDuplicateExecutionModes(ValidationState_t& _) {
+ using PerEntryKey = std::tuple<spv::ExecutionMode, uint32_t>;
+ using PerOperandKey = std::tuple<spv::ExecutionMode, uint32_t, uint32_t>;
+ std::set<PerEntryKey> seen_per_entry;
+ std::set<PerOperandKey> seen_per_operand;
+
+ const auto lookupMode = [&_](spv::ExecutionMode mode) -> std::string {
+ spv_operand_desc desc = nullptr;
+ if (_.grammar().lookupOperand(SPV_OPERAND_TYPE_EXECUTION_MODE,
+ static_cast<uint32_t>(mode),
+ &desc) == SPV_SUCCESS) {
+ return std::string(desc->name);
+ }
+ return "Unknown";
+ };
+
+ for (const auto& inst : _.ordered_instructions()) {
+ if (inst.opcode() != spv::Op::OpExecutionMode &&
+ inst.opcode() != spv::Op::OpExecutionModeId) {
+ continue;
+ }
+
+ const auto entry = inst.GetOperandAs<uint32_t>(0);
+ const auto mode = inst.GetOperandAs<spv::ExecutionMode>(1);
+ if (PerEntryExecutionMode(mode)) {
+ if (!seen_per_entry.insert(std::make_tuple(mode, entry)).second) {
+ return _.diag(SPV_ERROR_INVALID_ID, &inst)
+ << lookupMode(mode)
+ << " execution mode must not be specified multiple times per "
+ "entry point";
+ }
+ } else {
+ // Execution modes allowed multiple times all take a single operand.
+ const auto operand = inst.GetOperandAs<uint32_t>(2);
+ if (!seen_per_operand.insert(std::make_tuple(mode, entry, operand))
+ .second) {
+ return _.diag(SPV_ERROR_INVALID_ID, &inst)
+ << lookupMode(mode)
+ << " execution mode must not be specified multiple times for "
+ "the same entry point and operands";
+ }
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/source/val/validate_non_uniform.cpp b/third_party/SPIRV-Tools/source/val/validate_non_uniform.cpp
index af04e76af..75967d2ff 100644
--- a/third_party/SPIRV-Tools/source/val/validate_non_uniform.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_non_uniform.cpp
@@ -26,6 +26,207 @@ namespace spvtools {
namespace val {
namespace {
+spv_result_t ValidateGroupNonUniformElect(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsBoolScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar type";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformAnyAll(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsBoolScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar type";
+ }
+
+ if (!_.IsBoolScalarType(_.GetOperandTypeId(inst, 3))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Predicate must be a boolean scalar type";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformAllEqual(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsBoolScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar type";
+ }
+
+ const auto value_type = _.GetOperandTypeId(inst, 3);
+ if (!_.IsFloatScalarOrVectorType(value_type) &&
+ !_.IsIntScalarOrVectorType(value_type) &&
+ !_.IsBoolScalarOrVectorType(value_type)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a scalar or vector of integer, floating-point, or "
+ "boolean type";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformBroadcastShuffle(ValidationState_t& _,
+ const Instruction* inst) {
+ const auto type_id = inst->type_id();
+ if (!_.IsFloatScalarOrVectorType(type_id) &&
+ !_.IsIntScalarOrVectorType(type_id) &&
+ !_.IsBoolScalarOrVectorType(type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a scalar or vector of integer, floating-point, "
+ "or boolean type";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 3);
+ if (value_type_id != type_id) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The type of Value must match the Result type";
+ }
+
+ const auto GetOperandName = [](const spv::Op opcode) {
+ std::string operand;
+ switch (opcode) {
+ case spv::Op::OpGroupNonUniformBroadcast:
+ case spv::Op::OpGroupNonUniformShuffle:
+ operand = "Id";
+ break;
+ case spv::Op::OpGroupNonUniformShuffleXor:
+ operand = "Mask";
+ break;
+ case spv::Op::OpGroupNonUniformQuadBroadcast:
+ operand = "Index";
+ break;
+ case spv::Op::OpGroupNonUniformQuadSwap:
+ operand = "Direction";
+ break;
+ case spv::Op::OpGroupNonUniformShuffleUp:
+ case spv::Op::OpGroupNonUniformShuffleDown:
+ default:
+ operand = "Delta";
+ break;
+ }
+ return operand;
+ };
+
+ const auto id_type_id = _.GetOperandTypeId(inst, 4);
+ if (!_.IsUnsignedIntScalarType(id_type_id)) {
+ std::string operand = GetOperandName(inst->opcode());
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << operand << " must be an unsigned integer scalar";
+ }
+
+ const bool should_be_constant =
+ inst->opcode() == spv::Op::OpGroupNonUniformQuadSwap ||
+ ((inst->opcode() == spv::Op::OpGroupNonUniformBroadcast ||
+ inst->opcode() == spv::Op::OpGroupNonUniformQuadBroadcast) &&
+ _.version() < SPV_SPIRV_VERSION_WORD(1, 5));
+ if (should_be_constant) {
+ const auto id_id = inst->GetOperandAs<uint32_t>(4);
+ const auto id_op = _.GetIdOpcode(id_id);
+ if (!spvOpcodeIsConstant(id_op)) {
+ std::string operand = GetOperandName(inst->opcode());
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Before SPIR-V 1.5, " << operand
+ << " must be a constant instruction";
+ }
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformBroadcastFirst(ValidationState_t& _,
+ const Instruction* inst) {
+ const auto type_id = inst->type_id();
+ if (!_.IsFloatScalarOrVectorType(type_id) &&
+ !_.IsIntScalarOrVectorType(type_id) &&
+ !_.IsBoolScalarOrVectorType(type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a scalar or vector of integer, floating-point, "
+ "or boolean type";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 3);
+ if (value_type_id != type_id) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The type of Value must match the Result type";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformBallot(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsUnsignedIntVectorType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a 4-component unsigned integer vector";
+ }
+
+ if (_.GetDimension(inst->type_id()) != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a 4-component unsigned integer vector";
+ }
+
+ const auto pred_type_id = _.GetOperandTypeId(inst, 3);
+ if (!_.IsBoolScalarType(pred_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Predicate must be a boolean scalar";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformInverseBallot(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsBoolScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 3);
+ if (!_.IsUnsignedIntVectorType(value_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ if (_.GetDimension(value_type_id) != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformBallotBitExtract(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsBoolScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 3);
+ if (!_.IsUnsignedIntVectorType(value_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ if (_.GetDimension(value_type_id) != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ const auto id_type_id = _.GetOperandTypeId(inst, 4);
+ if (!_.IsUnsignedIntScalarType(id_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Id must be an unsigned integer scalar";
+ }
+
+ return SPV_SUCCESS;
+}
+
spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _,
const Instruction* inst) {
// Scope is already checked by ValidateExecutionScope() above.
@@ -60,6 +261,107 @@ spv_result_t ValidateGroupNonUniformBallotBitCount(ValidationState_t& _,
return SPV_SUCCESS;
}
+spv_result_t ValidateGroupNonUniformBallotFind(ValidationState_t& _,
+ const Instruction* inst) {
+ if (!_.IsUnsignedIntScalarType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be an unsigned integer scalar";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 3);
+ if (!_.IsUnsignedIntVectorType(value_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ if (_.GetDimension(value_type_id) != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Value must be a 4-component unsigned integer vector";
+ }
+
+ return SPV_SUCCESS;
+}
+
+spv_result_t ValidateGroupNonUniformArithmetic(ValidationState_t& _,
+ const Instruction* inst) {
+ const bool is_unsigned = inst->opcode() == spv::Op::OpGroupNonUniformUMin ||
+ inst->opcode() == spv::Op::OpGroupNonUniformUMax;
+ const bool is_float = inst->opcode() == spv::Op::OpGroupNonUniformFAdd ||
+ inst->opcode() == spv::Op::OpGroupNonUniformFMul ||
+ inst->opcode() == spv::Op::OpGroupNonUniformFMin ||
+ inst->opcode() == spv::Op::OpGroupNonUniformFMax;
+ const bool is_bool = inst->opcode() == spv::Op::OpGroupNonUniformLogicalAnd ||
+ inst->opcode() == spv::Op::OpGroupNonUniformLogicalOr ||
+ inst->opcode() == spv::Op::OpGroupNonUniformLogicalXor;
+ if (is_float) {
+ if (!_.IsFloatScalarOrVectorType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a floating-point scalar or vector";
+ }
+ } else if (is_bool) {
+ if (!_.IsBoolScalarOrVectorType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be a boolean scalar or vector";
+ }
+ } else if (is_unsigned) {
+ if (!_.IsUnsignedIntScalarOrVectorType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be an unsigned integer scalar or vector";
+ }
+ } else if (!_.IsIntScalarOrVectorType(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Result must be an integer scalar or vector";
+ }
+
+ const auto value_type_id = _.GetOperandTypeId(inst, 4);
+ if (value_type_id != inst->type_id()) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "The type of Value must match the Result type";
+ }
+
+ const auto group_op = inst->GetOperandAs<spv::GroupOperation>(3);
+ bool is_clustered_reduce = group_op == spv::GroupOperation::ClusteredReduce;
+ bool is_partitioned_nv =
+ group_op == spv::GroupOperation::PartitionedReduceNV ||
+ group_op == spv::GroupOperation::PartitionedInclusiveScanNV ||
+ group_op == spv::GroupOperation::PartitionedExclusiveScanNV;
+ if (inst->operands().size() <= 5) {
+ if (is_clustered_reduce) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "ClusterSize must be present when Operation is ClusteredReduce";
+ } else if (is_partitioned_nv) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Ballot must be present when Operation is PartitionedReduceNV, "
+ "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV";
+ }
+ } else {
+ const auto operand_id = inst->GetOperandAs<uint32_t>(5);
+ const auto* operand = _.FindDef(operand_id);
+ if (is_partitioned_nv) {
+ if (!operand || !_.IsIntScalarOrVectorType(operand->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Ballot must be a 4-component integer vector";
+ }
+
+ if (_.GetDimension(operand->type_id()) != 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Ballot must be a 4-component integer vector";
+ }
+ } else {
+ if (!operand || !_.IsUnsignedIntScalarType(operand->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "ClusterSize must be an unsigned integer scalar";
+ }
+
+ if (!spvOpcodeIsConstant(operand->opcode())) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "ClusterSize must be a constant instruction";
+ }
+ }
+ }
+ return SPV_SUCCESS;
+}
+
spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _,
const Instruction* inst) {
// Scope is already checked by ValidateExecutionScope() above.
@@ -87,20 +389,25 @@ spv_result_t ValidateGroupNonUniformRotateKHR(ValidationState_t& _,
if (inst->words().size() > 6) {
const uint32_t cluster_size_op_id = inst->GetOperandAs<uint32_t>(5);
- const uint32_t cluster_size_type = _.GetTypeId(cluster_size_op_id);
+ const Instruction* cluster_size_inst = _.FindDef(cluster_size_op_id);
+ const uint32_t cluster_size_type =
+ cluster_size_inst ? cluster_size_inst->type_id() : 0;
if (!_.IsUnsignedIntScalarType(cluster_size_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ClusterSize must be a scalar of integer type, whose "
"Signedness operand is 0.";
}
- uint64_t cluster_size;
- if (!_.GetConstantValUint64(cluster_size_op_id, &cluster_size)) {
+ if (!spvOpcodeIsConstant(cluster_size_inst->opcode())) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "ClusterSize must come from a constant instruction.";
}
- if ((cluster_size == 0) || ((cluster_size & (cluster_size - 1)) != 0)) {
+ uint64_t cluster_size;
+ const bool valid_const =
+ _.EvalConstantValUint64(cluster_size_op_id, &cluster_size);
+ if (valid_const &&
+ ((cluster_size == 0) || ((cluster_size & (cluster_size - 1)) != 0))) {
return _.diag(SPV_WARNING, inst)
<< "Behavior is undefined unless ClusterSize is at least 1 and a "
"power of 2.";
@@ -120,15 +427,63 @@ spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) {
const spv::Op opcode = inst->opcode();
if (spvOpcodeIsNonUniformGroupOperation(opcode)) {
- const uint32_t execution_scope = inst->word(3);
- if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
- return error;
+ // OpGroupNonUniformQuadAllKHR and OpGroupNonUniformQuadAnyKHR don't have
+ // scope paramter
+ if ((opcode != spv::Op::OpGroupNonUniformQuadAllKHR) &&
+ (opcode != spv::Op::OpGroupNonUniformQuadAnyKHR)) {
+ const uint32_t execution_scope = inst->GetOperandAs<uint32_t>(2);
+ if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
+ return error;
+ }
}
}
switch (opcode) {
+ case spv::Op::OpGroupNonUniformElect:
+ return ValidateGroupNonUniformElect(_, inst);
+ case spv::Op::OpGroupNonUniformAny:
+ case spv::Op::OpGroupNonUniformAll:
+ return ValidateGroupNonUniformAnyAll(_, inst);
+ case spv::Op::OpGroupNonUniformAllEqual:
+ return ValidateGroupNonUniformAllEqual(_, inst);
+ case spv::Op::OpGroupNonUniformBroadcast:
+ case spv::Op::OpGroupNonUniformShuffle:
+ case spv::Op::OpGroupNonUniformShuffleXor:
+ case spv::Op::OpGroupNonUniformShuffleUp:
+ case spv::Op::OpGroupNonUniformShuffleDown:
+ case spv::Op::OpGroupNonUniformQuadBroadcast:
+ case spv::Op::OpGroupNonUniformQuadSwap:
+ return ValidateGroupNonUniformBroadcastShuffle(_, inst);
+ case spv::Op::OpGroupNonUniformBroadcastFirst:
+ return ValidateGroupNonUniformBroadcastFirst(_, inst);
+ case spv::Op::OpGroupNonUniformBallot:
+ return ValidateGroupNonUniformBallot(_, inst);
+ case spv::Op::OpGroupNonUniformInverseBallot:
+ return ValidateGroupNonUniformInverseBallot(_, inst);
+ case spv::Op::OpGroupNonUniformBallotBitExtract:
+ return ValidateGroupNonUniformBallotBitExtract(_, inst);
case spv::Op::OpGroupNonUniformBallotBitCount:
return ValidateGroupNonUniformBallotBitCount(_, inst);
+ case spv::Op::OpGroupNonUniformBallotFindLSB:
+ case spv::Op::OpGroupNonUniformBallotFindMSB:
+ return ValidateGroupNonUniformBallotFind(_, inst);
+ case spv::Op::OpGroupNonUniformIAdd:
+ case spv::Op::OpGroupNonUniformFAdd:
+ case spv::Op::OpGroupNonUniformIMul:
+ case spv::Op::OpGroupNonUniformFMul:
+ case spv::Op::OpGroupNonUniformSMin:
+ case spv::Op::OpGroupNonUniformUMin:
+ case spv::Op::OpGroupNonUniformFMin:
+ case spv::Op::OpGroupNonUniformSMax:
+ case spv::Op::OpGroupNonUniformUMax:
+ case spv::Op::OpGroupNonUniformFMax:
+ case spv::Op::OpGroupNonUniformBitwiseAnd:
+ case spv::Op::OpGroupNonUniformBitwiseOr:
+ case spv::Op::OpGroupNonUniformBitwiseXor:
+ case spv::Op::OpGroupNonUniformLogicalAnd:
+ case spv::Op::OpGroupNonUniformLogicalOr:
+ case spv::Op::OpGroupNonUniformLogicalXor:
+ return ValidateGroupNonUniformArithmetic(_, inst);
case spv::Op::OpGroupNonUniformRotateKHR:
return ValidateGroupNonUniformRotateKHR(_, inst);
default:
diff --git a/third_party/SPIRV-Tools/source/val/validate_scopes.cpp b/third_party/SPIRV-Tools/source/val/validate_scopes.cpp
index 40c49d1ff..6b493538a 100644
--- a/third_party/SPIRV-Tools/source/val/validate_scopes.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_scopes.cpp
@@ -97,8 +97,10 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _,
// Vulkan 1.1 specific rules
if (_.context()->target_env != SPV_ENV_VULKAN_1_0) {
// Scope for Non Uniform Group Operations must be limited to Subgroup
- if (spvOpcodeIsNonUniformGroupOperation(opcode) &&
- value != spv::Scope::Subgroup) {
+ if ((spvOpcodeIsNonUniformGroupOperation(opcode) &&
+ (opcode != spv::Op::OpGroupNonUniformQuadAllKHR) &&
+ (opcode != spv::Op::OpGroupNonUniformQuadAnyKHR)) &&
+ (value != spv::Scope::Subgroup)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< _.VkErrorID(4642) << spvOpcodeString(opcode)
<< ": in Vulkan environment Execution scope is limited to "
@@ -178,6 +180,8 @@ spv_result_t ValidateExecutionScope(ValidationState_t& _,
// Scope for execution must be limited to Workgroup or Subgroup for
// non-uniform operations
if (spvOpcodeIsNonUniformGroupOperation(opcode) &&
+ opcode != spv::Op::OpGroupNonUniformQuadAllKHR &&
+ opcode != spv::Op::OpGroupNonUniformQuadAnyKHR &&
value != spv::Scope::Subgroup && value != spv::Scope::Workgroup) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
diff --git a/third_party/SPIRV-Tools/source/val/validate_type.cpp b/third_party/SPIRV-Tools/source/val/validate_type.cpp
index 430d81908..cb26a527c 100644
--- a/third_party/SPIRV-Tools/source/val/validate_type.cpp
+++ b/third_party/SPIRV-Tools/source/val/validate_type.cpp
@@ -24,21 +24,6 @@ namespace spvtools {
namespace val {
namespace {
-// Returns, as an int64_t, the literal value from an OpConstant or the
-// default value of an OpSpecConstant, assuming it is an integral type.
-// For signed integers, relies the rule that literal value is sign extended
-// to fill out to word granularity. Assumes that the constant value
-// has
-int64_t ConstantLiteralAsInt64(uint32_t width,
- const std::vector<uint32_t>& const_words) {
- const uint32_t lo_word = const_words[3];
- if (width <= 32) return int32_t(lo_word);
- assert(width <= 64);
- assert(const_words.size() > 4);
- const uint32_t hi_word = const_words[4]; // Must exist, per spec.
- return static_cast<int64_t>(uint64_t(lo_word) | uint64_t(hi_word) << 32);
-}
-
// Validates that type declarations are unique, unless multiple declarations
// of the same data type are allowed by the specification.
// (see section 2.8 Types and Variables)
@@ -252,29 +237,17 @@ spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) {
<< " is not a constant integer type.";
}
- switch (length->opcode()) {
- case spv::Op::OpSpecConstant:
- case spv::Op::OpConstant: {
- auto& type_words = const_result_type->words();
- const bool is_signed = type_words[3] > 0;
- const uint32_t width = type_words[2];
- const int64_t ivalue = ConstantLiteralAsInt64(width, length->words());
- if (ivalue == 0 || (ivalue < 0 && is_signed)) {
- return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpTypeArray Length <id> " << _.getIdName(length_id)
- << " default value must be at least 1: found " << ivalue;
- }
- } break;
- case spv::Op::OpConstantNull:
+ int64_t length_value;
+ if (_.EvalConstantValInt64(length_id, &length_value)) {
+ auto& type_words = const_result_type->words();
+ const bool is_signed = type_words[3] > 0;
+ if (length_value == 0 || (length_value < 0 && is_signed)) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
<< "OpTypeArray Length <id> " << _.getIdName(length_id)
- << " default value must be at least 1.";
- case spv::Op::OpSpecConstantOp:
- // Assume it's OK, rather than try to evaluate the operation.
- break;
- default:
- assert(0 && "bug in spvOpcodeIsConstant() or result type isn't int");
+ << " default value must be at least 1: found " << length_value;
+ }
}
+
return SPV_SUCCESS;
}
@@ -552,8 +525,8 @@ spv_result_t ValidateTypeForwardPointer(ValidationState_t& _,
return SPV_SUCCESS;
}
-spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _,
- const Instruction* inst) {
+spv_result_t ValidateTypeCooperativeMatrix(ValidationState_t& _,
+ const Instruction* inst) {
const auto component_type_index = 1;
const auto component_type_id =
inst->GetOperandAs<uint32_t>(component_type_index);
@@ -561,7 +534,7 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _,
if (!component_type || (spv::Op::OpTypeFloat != component_type->opcode() &&
spv::Op::OpTypeInt != component_type->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpTypeCooperativeMatrixNV Component Type <id> "
+ << "OpTypeCooperativeMatrix Component Type <id> "
<< _.getIdName(component_type_id)
<< " is not a scalar numerical type.";
}
@@ -572,7 +545,7 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _,
if (!scope || !_.IsIntScalarType(scope->type_id()) ||
!spvOpcodeIsConstant(scope->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpTypeCooperativeMatrixNV Scope <id> " << _.getIdName(scope_id)
+ << "OpTypeCooperativeMatrix Scope <id> " << _.getIdName(scope_id)
<< " is not a constant instruction with scalar integer type.";
}
@@ -582,7 +555,7 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _,
if (!rows || !_.IsIntScalarType(rows->type_id()) ||
!spvOpcodeIsConstant(rows->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpTypeCooperativeMatrixNV Rows <id> " << _.getIdName(rows_id)
+ << "OpTypeCooperativeMatrix Rows <id> " << _.getIdName(rows_id)
<< " is not a constant instruction with scalar integer type.";
}
@@ -592,10 +565,22 @@ spv_result_t ValidateTypeCooperativeMatrixNV(ValidationState_t& _,
if (!cols || !_.IsIntScalarType(cols->type_id()) ||
!spvOpcodeIsConstant(cols->opcode())) {
return _.diag(SPV_ERROR_INVALID_ID, inst)
- << "OpTypeCooperativeMatrixNV Cols <id> " << _.getIdName(cols_id)
+ << "OpTypeCooperativeMatrix Cols <id> " << _.getIdName(cols_id)
<< " is not a constant instruction with scalar integer type.";
}
+ if (inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) {
+ const auto use_index = 5;
+ const auto use_id = inst->GetOperandAs<uint32_t>(use_index);
+ const auto use = _.FindDef(use_id);
+ if (!use || !_.IsIntScalarType(use->type_id()) ||
+ !spvOpcodeIsConstant(use->opcode())) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "OpTypeCooperativeMatrixKHR Use <id> " << _.getIdName(use_id)
+ << " is not a constant instruction with scalar integer type.";
+ }
+ }
+
return SPV_SUCCESS;
}
} // namespace
@@ -640,7 +625,8 @@ spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) {
if (auto error = ValidateTypeForwardPointer(_, inst)) return error;
break;
case spv::Op::OpTypeCooperativeMatrixNV:
- if (auto error = ValidateTypeCooperativeMatrixNV(_, inst)) return error;
+ case spv::Op::OpTypeCooperativeMatrixKHR:
+ if (auto error = ValidateTypeCooperativeMatrix(_, inst)) return error;
break;
default:
break;
diff --git a/third_party/SPIRV-Tools/source/val/validation_state.cpp b/third_party/SPIRV-Tools/source/val/validation_state.cpp
index dbf0ba6d9..87322d2b9 100644
--- a/third_party/SPIRV-Tools/source/val/validation_state.cpp
+++ b/third_party/SPIRV-Tools/source/val/validation_state.cpp
@@ -21,6 +21,7 @@
#include "source/opcode.h"
#include "source/spirv_constant.h"
#include "source/spirv_target_env.h"
+#include "source/util/make_unique.h"
#include "source/val/basic_block.h"
#include "source/val/construct.h"
#include "source/val/function.h"
@@ -359,14 +360,16 @@ void ValidationState_t::RegisterCapability(spv::Capability cap) {
// Avoid redundant work. Otherwise the recursion could induce work
// quadrdatic in the capability dependency depth. (Ok, not much, but
// it's something.)
- if (module_capabilities_.Contains(cap)) return;
+ if (module_capabilities_.contains(cap)) return;
- module_capabilities_.Add(cap);
+ module_capabilities_.insert(cap);
spv_operand_desc desc;
if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
uint32_t(cap), &desc)) {
- CapabilitySet(desc->numCapabilities, desc->capabilities)
- .ForEach([this](spv::Capability c) { RegisterCapability(c); });
+ for (auto capability :
+ CapabilitySet(desc->numCapabilities, desc->capabilities)) {
+ RegisterCapability(capability);
+ }
}
switch (cap) {
@@ -418,9 +421,9 @@ void ValidationState_t::RegisterCapability(spv::Capability cap) {
}
void ValidationState_t::RegisterExtension(Extension ext) {
- if (module_extensions_.Contains(ext)) return;
+ if (module_extensions_.contains(ext)) return;
- module_extensions_.Add(ext);
+ module_extensions_.insert(ext);
switch (ext) {
case kSPV_AMD_gpu_shader_half_float:
@@ -608,6 +611,19 @@ void ValidationState_t::RegisterSampledImageConsumer(uint32_t sampled_image_id,
sampled_image_consumers_[sampled_image_id].push_back(consumer);
}
+void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer(
+ uint32_t texture_id, const Instruction* consumer0,
+ const Instruction* consumer1) {
+ if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) ||
+ HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM) ||
+ HasDecoration(texture_id, spv::Decoration::BlockMatchSamplerQCOM)) {
+ qcom_image_processing_consumers_.insert(consumer0->id());
+ if (consumer1) {
+ qcom_image_processing_consumers_.insert(consumer1->id());
+ }
+ }
+}
+
void ValidationState_t::RegisterStorageClassConsumer(
spv::StorageClass storage_class, Instruction* consumer) {
if (spvIsVulkanEnv(context()->target_env)) {
@@ -665,39 +681,39 @@ void ValidationState_t::RegisterStorageClassConsumer(
if (storage_class == spv::StorageClass::CallableDataKHR) {
std::string errorVUID = VkErrorID(4704);
function(consumer->function()->id())
- ->RegisterExecutionModelLimitation([errorVUID](
- spv::ExecutionModel model,
- std::string* message) {
- if (model != spv::ExecutionModel::RayGenerationKHR &&
- model != spv::ExecutionModel::ClosestHitKHR &&
- model != spv::ExecutionModel::CallableKHR &&
- model != spv::ExecutionModel::MissKHR) {
- if (message) {
- *message = errorVUID +
- "CallableDataKHR Storage Class is limited to "
- "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
- "MissKHR execution model";
- }
- return false;
- }
- return true;
- });
+ ->RegisterExecutionModelLimitation(
+ [errorVUID](spv::ExecutionModel model, std::string* message) {
+ if (model != spv::ExecutionModel::RayGenerationKHR &&
+ model != spv::ExecutionModel::ClosestHitKHR &&
+ model != spv::ExecutionModel::CallableKHR &&
+ model != spv::ExecutionModel::MissKHR) {
+ if (message) {
+ *message =
+ errorVUID +
+ "CallableDataKHR Storage Class is limited to "
+ "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
+ "MissKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
} else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) {
std::string errorVUID = VkErrorID(4705);
function(consumer->function()->id())
- ->RegisterExecutionModelLimitation([errorVUID](
- spv::ExecutionModel model,
- std::string* message) {
- if (model != spv::ExecutionModel::CallableKHR) {
- if (message) {
- *message = errorVUID +
- "IncomingCallableDataKHR Storage Class is limited to "
- "CallableKHR execution model";
- }
- return false;
- }
- return true;
- });
+ ->RegisterExecutionModelLimitation(
+ [errorVUID](spv::ExecutionModel model, std::string* message) {
+ if (model != spv::ExecutionModel::CallableKHR) {
+ if (message) {
+ *message =
+ errorVUID +
+ "IncomingCallableDataKHR Storage Class is limited to "
+ "CallableKHR execution model";
+ }
+ return false;
+ }
+ return true;
+ });
} else if (storage_class == spv::StorageClass::RayPayloadKHR) {
std::string errorVUID = VkErrorID(4698);
function(consumer->function()->id())
@@ -859,6 +875,7 @@ uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
return GetComponentType(inst->word(2));
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
return inst->word(2);
default:
@@ -886,6 +903,7 @@ uint32_t ValidationState_t::GetDimension(uint32_t id) const {
return inst->word(3);
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
// Actual dimension isn't known, return 0
return 0;
@@ -937,6 +955,20 @@ bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
return false;
}
+bool ValidationState_t::IsFloat16Vector2Or4Type(uint32_t id) const {
+ const Instruction* inst = FindDef(id);
+ assert(inst);
+
+ if (inst->opcode() == spv::Op::OpTypeVector) {
+ uint32_t vectorDim = GetDimension(id);
+ return IsFloatScalarType(GetComponentType(id)) &&
+ (vectorDim == 2 || vectorDim == 4) &&
+ (GetBitWidth(GetComponentType(id)) == 16);
+ }
+
+ return false;
+}
+
bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
if (!inst) {
@@ -1007,6 +1039,23 @@ bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
return false;
}
+bool ValidationState_t::IsUnsignedIntScalarOrVectorType(uint32_t id) const {
+ const Instruction* inst = FindDef(id);
+ if (!inst) {
+ return false;
+ }
+
+ if (inst->opcode() == spv::Op::OpTypeInt) {
+ return inst->GetOperandAs<uint32_t>(2) == 0;
+ }
+
+ if (inst->opcode() == spv::Op::OpTypeVector) {
+ return IsUnsignedIntScalarType(GetComponentType(id));
+ }
+
+ return false;
+}
+
bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 1;
@@ -1143,21 +1192,67 @@ bool ValidationState_t::IsAccelerationStructureType(uint32_t id) const {
bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const {
const Instruction* inst = FindDef(id);
+ return inst && (inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV ||
+ inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR);
+}
+
+bool ValidationState_t::IsCooperativeMatrixNVType(uint32_t id) const {
+ const Instruction* inst = FindDef(id);
return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV;
}
+bool ValidationState_t::IsCooperativeMatrixKHRType(uint32_t id) const {
+ const Instruction* inst = FindDef(id);
+ return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixKHR;
+}
+
+bool ValidationState_t::IsCooperativeMatrixAType(uint32_t id) const {
+ if (!IsCooperativeMatrixKHRType(id)) return false;
+ const Instruction* inst = FindDef(id);
+ uint64_t matrixUse = 0;
+ if (EvalConstantValUint64(inst->word(6), &matrixUse)) {
+ return matrixUse ==
+ static_cast<uint64_t>(spv::CooperativeMatrixUse::MatrixAKHR);
+ }
+ return false;
+}
+
+bool ValidationState_t::IsCooperativeMatrixBType(uint32_t id) const {
+ if (!IsCooperativeMatrixKHRType(id)) return false;
+ const Instruction* inst = FindDef(id);
+ uint64_t matrixUse = 0;
+ if (EvalConstantValUint64(inst->word(6), &matrixUse)) {
+ return matrixUse ==
+ static_cast<uint64_t>(spv::CooperativeMatrixUse::MatrixBKHR);
+ }
+ return false;
+}
+bool ValidationState_t::IsCooperativeMatrixAccType(uint32_t id) const {
+ if (!IsCooperativeMatrixKHRType(id)) return false;
+ const Instruction* inst = FindDef(id);
+ uint64_t matrixUse = 0;
+ if (EvalConstantValUint64(inst->word(6), &matrixUse)) {
+ return matrixUse == static_cast<uint64_t>(
+ spv::CooperativeMatrixUse::MatrixAccumulatorKHR);
+ }
+ return false;
+}
+
bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const {
- if (!IsCooperativeMatrixType(id)) return false;
+ if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id))
+ return false;
return IsFloatScalarType(FindDef(id)->word(2));
}
bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const {
- if (!IsCooperativeMatrixType(id)) return false;
+ if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id))
+ return false;
return IsIntScalarType(FindDef(id)->word(2));
}
bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const {
- if (!IsCooperativeMatrixType(id)) return false;
+ if (!IsCooperativeMatrixNVType(id) && !IsCooperativeMatrixKHRType(id))
+ return false;
return IsUnsignedIntScalarType(FindDef(id)->word(2));
}
@@ -1173,8 +1268,7 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
const auto m1_type = FindDef(m1);
const auto m2_type = FindDef(m2);
- if (m1_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV ||
- m2_type->opcode() != spv::Op::OpTypeCooperativeMatrixNV) {
+ if (m1_type->opcode() != m2_type->opcode()) {
return diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected cooperative matrix types";
}
@@ -1224,6 +1318,21 @@ spv_result_t ValidationState_t::CooperativeMatrixShapesMatch(
<< "identical";
}
+ if (m1_type->opcode() == spv::Op::OpTypeCooperativeMatrixKHR) {
+ uint32_t m1_use_id = m1_type->GetOperandAs<uint32_t>(5);
+ uint32_t m2_use_id = m2_type->GetOperandAs<uint32_t>(5);
+ std::tie(m1_is_int32, m1_is_const_int32, m1_value) =
+ EvalInt32IfConst(m1_use_id);
+ std::tie(m2_is_int32, m2_is_const_int32, m2_value) =
+ EvalInt32IfConst(m2_use_id);
+
+ if (m1_is_const_int32 && m2_is_const_int32 && m1_value != m2_value) {
+ return diag(SPV_ERROR_INVALID_DATA, inst)
+ << "Expected Use of Matrix type and Result Type to be "
+ << "identical";
+ }
+ }
+
return SPV_SUCCESS;
}
@@ -1232,20 +1341,23 @@ uint32_t ValidationState_t::GetOperandTypeId(const Instruction* inst,
return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
}
-bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
+bool ValidationState_t::EvalConstantValUint64(uint32_t id,
+ uint64_t* val) const {
const Instruction* inst = FindDef(id);
if (!inst) {
assert(0 && "Instruction not found");
return false;
}
- if (inst->opcode() != spv::Op::OpConstant &&
- inst->opcode() != spv::Op::OpSpecConstant)
- return false;
-
if (!IsIntScalarType(inst->type_id())) return false;
- if (inst->words().size() == 4) {
+ if (inst->opcode() == spv::Op::OpConstantNull) {
+ *val = 0;
+ } else if (inst->opcode() != spv::Op::OpConstant) {
+ // Spec constant values cannot be evaluated so don't consider constant for
+ // static validation
+ return false;
+ } else if (inst->words().size() == 4) {
*val = inst->word(3);
} else {
assert(inst->words().size() == 5);
@@ -1255,6 +1367,32 @@ bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
return true;
}
+bool ValidationState_t::EvalConstantValInt64(uint32_t id, int64_t* val) const {
+ const Instruction* inst = FindDef(id);
+ if (!inst) {
+ assert(0 && "Instruction not found");
+ return false;
+ }
+
+ if (!IsIntScalarType(inst->type_id())) return false;
+
+ if (inst->opcode() == spv::Op::OpConstantNull) {
+ *val = 0;
+ } else if (inst->opcode() != spv::Op::OpConstant) {
+ // Spec constant values cannot be evaluated so don't consider constant for
+ // static validation
+ return false;
+ } else if (inst->words().size() == 4) {
+ *val = int32_t(inst->word(3));
+ } else {
+ assert(inst->words().size() == 5);
+ const uint32_t lo_word = inst->word(3);
+ const uint32_t hi_word = inst->word(4);
+ *val = static_cast<int64_t>(uint64_t(lo_word) | uint64_t(hi_word) << 32);
+ }
+ return true;
+}
+
std::tuple<bool, bool, uint32_t> ValidationState_t::EvalInt32IfConst(
uint32_t id) const {
const Instruction* const inst = FindDef(id);
@@ -1489,6 +1627,7 @@ bool ValidationState_t::ContainsType(
case spv::Op::OpTypeImage:
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypeCooperativeMatrixNV:
+ case spv::Op::OpTypeCooperativeMatrixKHR:
return ContainsType(inst->GetOperandAs<uint32_t>(1u), f,
traverse_all_types);
case spv::Op::OpTypePointer:
@@ -2030,6 +2169,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-None-04644);
case 4645:
return VUID_WRAP(VUID-StandaloneSpirv-None-04645);
+ case 4650:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04650);
case 4651:
return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651);
case 4652:
@@ -2048,8 +2189,6 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
case 4659:
return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659);
- case 4662:
- return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662);
case 4663:
return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663);
case 4664:
@@ -2078,14 +2217,20 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
case 4699:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
+ case 4700:
+ return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700);
case 4701:
return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
+ case 4702:
+ return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04702);
case 4703:
return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
case 4704:
return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
case 4705:
return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
+ case 4706:
+ return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04706);
case 7119:
return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119);
case 4708:
@@ -2144,6 +2289,8 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
case 6672:
return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
+ case 6673:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-06673);
case 6674:
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
case 6675:
@@ -2164,6 +2311,24 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808);
case 6925:
return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925);
+ case 7041:
+ return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07041);
+ case 7043:
+ return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07043);
+ case 7044:
+ return VUID_WRAP(VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07044);
+ case 7047:
+ return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07047);
+ case 7049:
+ return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07049);
+ case 7050:
+ return VUID_WRAP(VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07050);
+ case 7053:
+ return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07053);
+ case 7055:
+ return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07055);
+ case 7056:
+ return VUID_WRAP(VUID-PrimitiveTriangleIndicesEXT-PrimitiveTriangleIndicesEXT-07056);
case 7102:
return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102);
case 7320:
@@ -2180,6 +2345,14 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-Component-07703);
case 7951:
return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-07951);
+ case 8721:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08721);
+ case 8722:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08722);
+ case 8973:
+ return VUID_WRAP(VUID-StandaloneSpirv-Pointer-08973);
+ case 9638:
+ return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-09638);
default:
return ""; // unknown id
}
diff --git a/third_party/SPIRV-Tools/source/val/validation_state.h b/third_party/SPIRV-Tools/source/val/validation_state.h
index 4d5ac0061..27acdcc2f 100644
--- a/third_party/SPIRV-Tools/source/val/validation_state.h
+++ b/third_party/SPIRV-Tools/source/val/validation_state.h
@@ -317,7 +317,7 @@ class ValidationState_t {
/// Returns true if the capability is enabled in the module.
bool HasCapability(spv::Capability cap) const {
- return module_capabilities_.Contains(cap);
+ return module_capabilities_.contains(cap);
}
/// Returns a reference to the set of capabilities in the module.
@@ -328,7 +328,7 @@ class ValidationState_t {
/// Returns true if the extension is enabled in the module.
bool HasExtension(Extension ext) const {
- return module_extensions_.Contains(ext);
+ return module_extensions_.contains(ext);
}
/// Returns true if any of the capabilities is enabled, or if |capabilities|
@@ -485,6 +485,13 @@ class ValidationState_t {
void RegisterSampledImageConsumer(uint32_t sampled_image_id,
Instruction* consumer);
+ // Record a cons_id as a consumer of texture_id
+ // if texture 'texture_id' has a QCOM image processing decoration
+ // and consumer is a load or a sampled image instruction
+ void RegisterQCOMImageProcessingTextureConsumer(uint32_t texture_id,
+ const Instruction* consumer0,
+ const Instruction* consumer1);
+
// Record a function's storage class consumer instruction
void RegisterStorageClassConsumer(spv::StorageClass storage_class,
Instruction* consumer);
@@ -595,6 +602,7 @@ class ValidationState_t {
bool IsVoidType(uint32_t id) const;
bool IsFloatScalarType(uint32_t id) const;
bool IsFloatVectorType(uint32_t id) const;
+ bool IsFloat16Vector2Or4Type(uint32_t id) const;
bool IsFloatScalarOrVectorType(uint32_t id) const;
bool IsFloatMatrixType(uint32_t id) const;
bool IsIntScalarType(uint32_t id) const;
@@ -602,6 +610,7 @@ class ValidationState_t {
bool IsIntScalarOrVectorType(uint32_t id) const;
bool IsUnsignedIntScalarType(uint32_t id) const;
bool IsUnsignedIntVectorType(uint32_t id) const;
+ bool IsUnsignedIntScalarOrVectorType(uint32_t id) const;
bool IsSignedIntScalarType(uint32_t id) const;
bool IsSignedIntVectorType(uint32_t id) const;
bool IsBoolScalarType(uint32_t id) const;
@@ -610,6 +619,11 @@ class ValidationState_t {
bool IsPointerType(uint32_t id) const;
bool IsAccelerationStructureType(uint32_t id) const;
bool IsCooperativeMatrixType(uint32_t id) const;
+ bool IsCooperativeMatrixNVType(uint32_t id) const;
+ bool IsCooperativeMatrixKHRType(uint32_t id) const;
+ bool IsCooperativeMatrixAType(uint32_t id) const;
+ bool IsCooperativeMatrixBType(uint32_t id) const;
+ bool IsCooperativeMatrixAccType(uint32_t id) const;
bool IsFloatCooperativeMatrixType(uint32_t id) const;
bool IsIntCooperativeMatrixType(uint32_t id) const;
bool IsUnsignedIntCooperativeMatrixType(uint32_t id) const;
@@ -634,10 +648,6 @@ class ValidationState_t {
const std::function<bool(const Instruction*)>& f,
bool traverse_all_types = true) const;
- // Gets value from OpConstant and OpSpecConstant as uint64.
- // Returns false on failure (no instruction, wrong instruction, not int).
- bool GetConstantValUint64(uint32_t id, uint64_t* val) const;
-
// Returns type_id if id has type or zero otherwise.
uint32_t GetTypeId(uint32_t id) const;
@@ -712,6 +722,14 @@ class ValidationState_t {
pointer_to_storage_image_.insert(type_id);
}
+ // Tries to evaluate a any scalar integer OpConstant as uint64.
+ // OpConstantNull is defined as zero for scalar int (will return true)
+ // OpSpecConstant* return false since their values cannot be relied upon
+ // during validation.
+ bool EvalConstantValUint64(uint32_t id, uint64_t* val) const;
+ // Same as EvalConstantValUint64 but returns a signed int
+ bool EvalConstantValInt64(uint32_t id, int64_t* val) const;
+
// Tries to evaluate a 32-bit signed or unsigned scalar integer constant.
// Returns tuple <is_int32, is_const_int32, value>.
// OpSpecConstant* return |is_const_int32| as false since their values cannot
@@ -786,6 +804,13 @@ class ValidationState_t {
current_layout_section_ = section;
}
+ // Check if instruction 'id' is a consumer of a texture decorated
+ // with a QCOM image processing decoration
+ bool IsQCOMImageProcessingTextureConsumer(uint32_t id) {
+ return qcom_image_processing_consumers_.find(id) !=
+ qcom_image_processing_consumers_.end();
+ }
+
private:
ValidationState_t(const ValidationState_t&);
@@ -820,6 +845,10 @@ class ValidationState_t {
std::unordered_map<uint32_t, std::vector<Instruction*>>
sampled_image_consumers_;
+ /// Stores load instructions that load textures used
+ // in QCOM image processing functions
+ std::unordered_set<uint32_t> qcom_image_processing_consumers_;
+
/// A map of operand IDs and their names defined by the OpName instruction
std::unordered_map<uint32_t, std::string> operand_names_;
diff --git a/third_party/SPIRV-Tools/source/wasm/build.sh b/third_party/SPIRV-Tools/source/wasm/build.sh
index 4f7b701c8..69468c9ce 100755
--- a/third_party/SPIRV-Tools/source/wasm/build.sh
+++ b/third_party/SPIRV-Tools/source/wasm/build.sh
@@ -45,7 +45,7 @@ build() {
emcc \
--bind \
-I../../include \
- -std=c++11 \
+ -std=c++17 \
../../source/wasm/spirv-tools.cpp \
source/libSPIRV-Tools.a \
-o spirv-tools.js \
diff --git a/third_party/SPIRV-Tools/test/CMakeLists.txt b/third_party/SPIRV-Tools/test/CMakeLists.txt
index 37c5e1d51..40c64f806 100644
--- a/third_party/SPIRV-Tools/test/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/CMakeLists.txt
@@ -12,22 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+if (${SPIRV_SKIP_TESTS})
+ return()
+endif()
+
+if (TARGET gmock_main)
+ message(STATUS "Found Google Mock, building tests.")
+else()
+ message(STATUS "Did not find googletest, tests will not be built. "
+ "To enable tests place googletest in '<spirv-dir>/external/googletest'.")
+endif()
+
# Add a SPIR-V Tools unit test. Signature:
# add_spvtools_unittest(
# TARGET target_name
# SRCS src_file.h src_file.cpp
# LIBS lib1 lib2
# )
-
-if (NOT "${SPIRV_SKIP_TESTS}")
- if (TARGET gmock_main)
- message(STATUS "Found Google Mock, building tests.")
- else()
- message(STATUS "Did not find googletest, tests will not be built. "
- "To enable tests place googletest in '<spirv-dir>/external/googletest'.")
- endif()
-endif()
-
function(add_spvtools_unittest)
if (NOT "${SPIRV_SKIP_TESTS}" AND TARGET gmock_main)
set(one_value_args TARGET PCH_FILE)
@@ -111,7 +112,6 @@ set(TEST_SOURCES
hex_float_test.cpp
immediate_int_test.cpp
libspirv_macros_test.cpp
- log_test.cpp
named_id_test.cpp
name_mapper_test.cpp
opcode_make_test.cpp
diff --git a/third_party/SPIRV-Tools/test/binary_parse_test.cpp b/third_party/SPIRV-Tools/test/binary_parse_test.cpp
index 50710cd13..1a868dbae 100644
--- a/third_party/SPIRV-Tools/test/binary_parse_test.cpp
+++ b/third_party/SPIRV-Tools/test/binary_parse_test.cpp
@@ -1154,7 +1154,10 @@ INSTANTIATE_TEST_SUITE_P(
{"%2 = OpSpecConstantOp %1 !1000 %2",
"Invalid OpSpecConstantOp opcode: 1000"},
{"OpCapability !9999", "Invalid capability operand: 9999"},
- {"OpSource !9999 100", "Invalid source language operand: 9999"},
+ {"OpSource !9999 100",
+ "Invalid source language operand: 9999, if you are creating a new "
+ "source language please use value 0 (Unknown) and when ready, add "
+ "your source language to SPRIV-Headers"},
{"OpEntryPoint !9999", "Invalid execution model operand: 9999"},
{"OpMemoryModel !9999", "Invalid addressing model operand: 9999"},
{"OpMemoryModel Logical !9999", "Invalid memory model operand: 9999"},
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp
index 9944c2cf1..bd5a7d587 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/OpExtInst_in_src_only_autogen.cpp
@@ -95,8 +95,7 @@ TEST(DiffTest, OpextinstInSrcOnly) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 15
-+; Bound: 16
+ ; Bound: 15
; Schema: 0
OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
@@ -199,8 +198,7 @@ TEST(DiffTest, OpextinstInSrcOnlyNoDebug) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 15
-+; Bound: 16
+ ; Bound: 15
; Schema: 0
OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/basic_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/basic_autogen.cpp
index f3afc701b..d4b6846bf 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/basic_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/basic_autogen.cpp
@@ -129,7 +129,7 @@ TEST(DiffTest, Basic) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 36
++; Bound: 30
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
@@ -272,7 +272,7 @@ OpFunctionEnd
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 36
++; Bound: 30
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
@@ -324,7 +324,7 @@ TEST(DiffTest, BasicDumpIds) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 36
++; Bound: 30
; Schema: 0
OpCapability Shader
+%27 = OpExtInstImport "GLSL.std.450"
@@ -384,8 +384,8 @@ TEST(DiffTest, BasicDumpIds) {
6 -> 14 [TypeInt]
13 -> 19 [TypePointer]
14 -> 27 [Variable]
- 15 -> 34 [Constant]
- 16 -> 35 [TypeArray]
+ 15 -> 28 [Constant]
+ 16 -> 29 [TypeArray]
17 -> 11 [TypeStruct]
18 -> 12 [TypePointer]
19 -> 13 [Variable]
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/constant_array_size_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/constant_array_size_autogen.cpp
index 16975ff47..2b6d7d809 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/constant_array_size_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/constant_array_size_autogen.cpp
@@ -125,7 +125,7 @@ TEST(DiffTest, ConstantArraySize) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 34
++; Bound: 28
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -259,7 +259,7 @@ OpFunctionEnd
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 34
++; Bound: 28
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/diff_test_files_autogen.cmake b/third_party/SPIRV-Tools/test/diff/diff_files/diff_test_files_autogen.cmake
index 6440d0b9c..51cb62fab 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/diff_test_files_autogen.cmake
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/diff_test_files_autogen.cmake
@@ -36,6 +36,7 @@ list(APPEND DIFF_TEST_FILES
"diff_files/large_functions_small_diffs_autogen.cpp"
"diff_files/multiple_different_entry_points_autogen.cpp"
"diff_files/multiple_same_entry_points_autogen.cpp"
+"diff_files/ray_query_types_autogen.cpp"
"diff_files/reordered_if_blocks_autogen.cpp"
"diff_files/reordered_switch_blocks_autogen.cpp"
"diff_files/small_functions_small_diffs_autogen.cpp"
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_fragment_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_fragment_autogen.cpp
index 0d34654f8..ec9074c64 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_fragment_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_fragment_autogen.cpp
@@ -977,7 +977,7 @@ OpFunctionEnd
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 82
-+; Bound: 92
++; Bound: 89
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -1030,8 +1030,7 @@ OpFunctionEnd
+OpDecorate %83 DescriptorSet 0
+OpDecorate %83 Binding 0
OpDecorate %32 RelaxedPrecision
--OpDecorate %33 RelaxedPrecision
-+OpDecorate %84 RelaxedPrecision
+ OpDecorate %33 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
OpDecorate %38 RelaxedPrecision
@@ -1040,10 +1039,8 @@ OpFunctionEnd
OpDecorate %42 RelaxedPrecision
OpDecorate %43 RelaxedPrecision
OpDecorate %48 RelaxedPrecision
--OpDecorate %49 RelaxedPrecision
--OpDecorate %50 RelaxedPrecision
-+OpDecorate %85 RelaxedPrecision
-+OpDecorate %86 RelaxedPrecision
+ OpDecorate %49 RelaxedPrecision
+ OpDecorate %50 RelaxedPrecision
OpDecorate %52 RelaxedPrecision
OpDecorate %53 RelaxedPrecision
OpDecorate %54 RelaxedPrecision
@@ -1082,13 +1079,13 @@ OpFunctionEnd
%61 = OpTypeVoid
%69 = OpConstant %16 0
%78 = OpConstant %16 1
-+%88 = OpTypePointer Private %2
++%85 = OpTypePointer Private %2
%3 = OpTypePointer Input %2
%7 = OpTypePointer UniformConstant %6
%10 = OpTypePointer UniformConstant %9
%13 = OpTypePointer Uniform %12
%19 = OpTypePointer Uniform %18
-+%89 = OpTypePointer Private %2
++%86 = OpTypePointer Private %2
%21 = OpTypePointer Output %2
%28 = OpTypePointer Uniform %27
%30 = OpTypePointer Function %2
@@ -1106,19 +1103,16 @@ OpFunctionEnd
%22 = OpVariable %21 Output
-%29 = OpVariable %28 Uniform
+%83 = OpVariable %28 Uniform
-+%90 = OpConstant %23 0
-+%91 = OpConstant %1 0.5
++%87 = OpConstant %23 0
++%88 = OpConstant %1 0.5
%32 = OpFunction %2 None %31
--%33 = OpFunctionParameter %30
-+%84 = OpFunctionParameter %30
+ %33 = OpFunctionParameter %30
%34 = OpLabel
%36 = OpLoad %6 %8
--%37 = OpLoad %2 %33
-+%37 = OpLoad %2 %84
+ %37 = OpLoad %2 %33
%38 = OpVectorShuffle %35 %37 %37 0 1
%39 = OpImageSampleImplicitLod %2 %36 %38
--%41 = OpLoad %2 %33
-+%41 = OpLoad %2 %84
+ %41 = OpLoad %2 %33
%42 = OpVectorShuffle %35 %41 %41 2 3
%43 = OpConvertFToS %40 %42
%44 = OpLoad %9 %11
@@ -1127,16 +1121,12 @@ OpFunctionEnd
OpReturnValue %46
OpFunctionEnd
%48 = OpFunction %2 None %47
--%49 = OpFunctionParameter %30
--%50 = OpFunctionParameter %30
-+%85 = OpFunctionParameter %30
-+%86 = OpFunctionParameter %30
+ %49 = OpFunctionParameter %30
+ %50 = OpFunctionParameter %30
%51 = OpLabel
--%52 = OpLoad %2 %49
-+%52 = OpLoad %2 %85
+ %52 = OpLoad %2 %49
%53 = OpVectorShuffle %35 %52 %52 0 1
--%54 = OpLoad %2 %50
-+%54 = OpLoad %2 %86
+ %54 = OpLoad %2 %50
%55 = OpVectorShuffle %35 %54 %54 2 3
%56 = OpCompositeExtract %1 %53 0
%57 = OpCompositeExtract %1 %53 1
@@ -1154,9 +1144,9 @@ OpFunctionEnd
OpStore %65 %66
%67 = OpFunctionCall %2 %32 %65
-%71 = OpAccessChain %70 %14 %69
-+%87 = OpAccessChain %70 %82 %69
++%84 = OpAccessChain %70 %82 %69
-%72 = OpLoad %2 %71
-+%72 = OpLoad %2 %87
++%72 = OpLoad %2 %84
OpStore %68 %72
-%74 = OpAccessChain %70 %20 %69 %69
+%74 = OpAccessChain %70 %14 %69 %69
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_vertex_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_vertex_autogen.cpp
index f65ee5a19..134ebb4a5 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_vertex_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/different_decorations_vertex_autogen.cpp
@@ -777,7 +777,7 @@ OpFunctionEnd
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 58
-+; Bound: 79
++; Bound: 77
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -817,12 +817,10 @@ OpFunctionEnd
-OpMemberDecorate %23 3 BuiltIn CullDistance
OpDecorate %23 Block
OpDecorate %28 RelaxedPrecision
--OpDecorate %29 RelaxedPrecision
-+OpDecorate %59 RelaxedPrecision
+ OpDecorate %29 RelaxedPrecision
OpDecorate %31 RelaxedPrecision
OpDecorate %32 RelaxedPrecision
--OpDecorate %33 RelaxedPrecision
-+OpDecorate %60 RelaxedPrecision
+ OpDecorate %33 RelaxedPrecision
OpDecorate %35 RelaxedPrecision
OpDecorate %36 RelaxedPrecision
OpDecorate %37 RelaxedPrecision
@@ -845,9 +843,9 @@ OpFunctionEnd
+%23 = OpTypeStruct %2
%38 = OpTypeVoid
%45 = OpConstant %12 0
-+%65 = OpTypePointer Private %2
++%63 = OpTypePointer Private %2
%3 = OpTypePointer Input %2
-+%66 = OpTypePointer Private %2
++%64 = OpTypePointer Private %2
%7 = OpTypePointer Output %2
%10 = OpTypePointer Uniform %9
%18 = OpTypePointer Uniform %17
@@ -865,26 +863,21 @@ OpFunctionEnd
-%19 = OpVariable %18 Uniform
+%19 = OpVariable %10 Uniform
%20 = OpVariable %7 Output
-+%58 = OpVariable %66 Private
++%58 = OpVariable %64 Private
%25 = OpVariable %24 Output
-+%67 = OpConstant %13 0
-+%68 = OpConstant %1 0.5
++%65 = OpConstant %13 0
++%66 = OpConstant %1 0.5
%28 = OpFunction %2 None %27
--%29 = OpFunctionParameter %26
-+%59 = OpFunctionParameter %26
+ %29 = OpFunctionParameter %26
%30 = OpLabel
--%31 = OpLoad %2 %29
-+%31 = OpLoad %2 %59
+ %31 = OpLoad %2 %29
OpReturnValue %31
OpFunctionEnd
%32 = OpFunction %2 None %27
--%33 = OpFunctionParameter %26
-+%60 = OpFunctionParameter %26
+ %33 = OpFunctionParameter %26
%34 = OpLabel
--%35 = OpLoad %2 %33
-+%35 = OpLoad %2 %60
--%36 = OpLoad %2 %33
-+%36 = OpLoad %2 %60
+ %35 = OpLoad %2 %33
+ %36 = OpLoad %2 %33
%37 = OpFAdd %2 %35 %36
OpReturnValue %37
OpFunctionEnd
@@ -894,41 +887,41 @@ OpFunctionEnd
%50 = OpVariable %26 Function
%53 = OpVariable %26 Function
-%43 = OpLoad %2 %4
-+%61 = OpLoad %2 %5
++%59 = OpLoad %2 %5
-OpStore %42 %43
-+OpStore %42 %61
++OpStore %42 %59
%44 = OpFunctionCall %2 %28 %42
-%47 = OpAccessChain %46 %11 %45
-+%62 = OpAccessChain %46 %19 %45
++%60 = OpAccessChain %46 %19 %45
-%48 = OpLoad %2 %47
-+%48 = OpLoad %2 %62
++%48 = OpLoad %2 %60
%49 = OpFAdd %2 %44 %48
-OpStore %8 %49
+OpStore %20 %49
-%51 = OpLoad %2 %5
-+%63 = OpLoad %2 %6
++%61 = OpLoad %2 %6
-OpStore %50 %51
-+OpStore %50 %63
++OpStore %50 %61
%52 = OpFunctionCall %2 %32 %50
-%54 = OpLoad %2 %6
-+%64 = OpLoad %2 %4
++%62 = OpLoad %2 %4
-OpStore %53 %54
-+OpStore %53 %64
++OpStore %53 %62
%55 = OpFunctionCall %2 %28 %53
%56 = OpFAdd %2 %52 %55
%57 = OpAccessChain %7 %25 %45
OpStore %57 %56
-+%69 = OpAccessChain %7 %25 %67
-+%70 = OpLoad %2 %69
-+%71 = OpCompositeExtract %1 %70 0
-+%72 = OpCompositeExtract %1 %70 1
-+%73 = OpCompositeExtract %1 %70 2
-+%74 = OpCompositeExtract %1 %70 3
-+%76 = OpFNegate %1 %71
-+%77 = OpFAdd %1 %73 %74
-+%78 = OpFMul %1 %77 %68
-+%75 = OpCompositeConstruct %2 %72 %76 %78 %74
-+OpStore %69 %75
++%67 = OpAccessChain %7 %25 %65
++%68 = OpLoad %2 %67
++%69 = OpCompositeExtract %1 %68 0
++%70 = OpCompositeExtract %1 %68 1
++%71 = OpCompositeExtract %1 %68 2
++%72 = OpCompositeExtract %1 %68 3
++%74 = OpFNegate %1 %69
++%75 = OpFAdd %1 %71 %72
++%76 = OpFMul %1 %75 %66
++%73 = OpCompositeConstruct %2 %70 %74 %76 %72
++OpStore %67 %73
OpReturn
OpFunctionEnd
)";
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/different_function_parameter_count_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/different_function_parameter_count_autogen.cpp
index 3a077fb0e..e31a4a89e 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/different_function_parameter_count_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/different_function_parameter_count_autogen.cpp
@@ -128,7 +128,7 @@ TEST(DiffTest, DifferentFunctionParameterCount) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 25
-+; Bound: 33
++; Bound: 31
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -143,7 +143,7 @@ TEST(DiffTest, DifferentFunctionParameterCount) {
+OpName %26 "v2"
OpName %20 "o"
OpName %23 "param"
-+OpName %31 "param"
++OpName %29 "param"
OpDecorate %20 RelaxedPrecision
OpDecorate %20 Location 0
%2 = OpTypeVoid
@@ -162,13 +162,13 @@ TEST(DiffTest, DifferentFunctionParameterCount) {
%4 = OpFunction %2 None %3
%5 = OpLabel
%23 = OpVariable %8 Function
-+%31 = OpVariable %8 Function
++%29 = OpVariable %8 Function
OpStore %23 %22
-%24 = OpFunctionCall %7 %11 %23
-+OpStore %31 %15
-+%32 = OpFunctionCall %7 %11 %23 %31
++OpStore %29 %15
++%30 = OpFunctionCall %7 %11 %23 %29
-OpStore %20 %24
-+OpStore %20 %32
++OpStore %20 %30
OpReturn
OpFunctionEnd
-%11 = OpFunction %7 None %9
@@ -280,7 +280,7 @@ TEST(DiffTest, DifferentFunctionParameterCountNoDebug) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 25
-+; Bound: 34
++; Bound: 31
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -306,28 +306,26 @@ TEST(DiffTest, DifferentFunctionParameterCountNoDebug) {
%4 = OpFunction %2 None %3
%5 = OpLabel
%23 = OpVariable %8 Function
-+%32 = OpVariable %8 Function
++%29 = OpVariable %8 Function
OpStore %23 %22
-%24 = OpFunctionCall %7 %11 %23
-+OpStore %32 %15
-+%33 = OpFunctionCall %7 %11 %23 %32
++OpStore %29 %15
++%30 = OpFunctionCall %7 %11 %23 %29
-OpStore %20 %24
-+OpStore %20 %33
++OpStore %20 %30
OpReturn
OpFunctionEnd
-%11 = OpFunction %7 None %9
+%11 = OpFunction %7 None %25
--%10 = OpFunctionParameter %8
+ %10 = OpFunctionParameter %8
+%26 = OpFunctionParameter %8
-+%27 = OpFunctionParameter %8
%12 = OpLabel
--%13 = OpLoad %7 %10
-+%13 = OpLoad %7 %26
+ %13 = OpLoad %7 %10
-%16 = OpFAdd %7 %13 %15
-+%28 = OpLoad %7 %27
-+%29 = OpFAdd %7 %13 %28
++%27 = OpLoad %7 %26
++%28 = OpFAdd %7 %13 %27
-OpReturnValue %16
-+OpReturnValue %29
++OpReturnValue %28
OpFunctionEnd
)";
Options options;
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/extra_if_block_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/extra_if_block_autogen.cpp
index 4f9131987..fee34aea5 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/extra_if_block_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/extra_if_block_autogen.cpp
@@ -303,7 +303,7 @@ TEST(DiffTest, ExtraIfBlock) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 69
-+; Bound: 81
++; Bound: 77
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -352,10 +352,10 @@ TEST(DiffTest, ExtraIfBlock) {
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
-+OpDecorate %72 RelaxedPrecision
++OpDecorate %70 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
-+OpDecorate %77 RelaxedPrecision
-+OpDecorate %78 RelaxedPrecision
++OpDecorate %75 RelaxedPrecision
++OpDecorate %76 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
@@ -383,7 +383,7 @@ TEST(DiffTest, ExtraIfBlock) {
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
-+%76 = OpConstant %6 0.100000001
++%74 = OpConstant %6 0.100000001
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
@@ -439,20 +439,20 @@ TEST(DiffTest, ExtraIfBlock) {
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
-+%71 = OpAccessChain %21 %18 %32
-+%72 = OpLoad %15 %71
-+%73 = OpINotEqual %25 %72 %24
-+OpSelectionMerge %75 None
-+OpBranchConditional %73 %74 %75
-+%74 = OpLabel
++%69 = OpAccessChain %21 %18 %32
++%70 = OpLoad %15 %69
++%71 = OpINotEqual %25 %70 %24
++OpSelectionMerge %73 None
++OpBranchConditional %71 %72 %73
++%72 = OpLabel
%57 = OpLoad %6 %45
-+%77 = OpFSub %6 %57 %76
-+OpStore %45 %77
-+OpBranch %75
-+%75 = OpLabel
-+%78 = OpLoad %6 %45
++%75 = OpFSub %6 %57 %74
++OpStore %45 %75
++OpBranch %73
++%73 = OpLabel
++%76 = OpLoad %6 %45
-%58 = OpExtInst %6 %1 Exp %57
-+%58 = OpExtInst %6 %1 Exp %78
++%58 = OpExtInst %6 %1 Exp %76
OpReturnValue %58
OpFunctionEnd
)";
@@ -716,7 +716,7 @@ TEST(DiffTest, ExtraIfBlockNoDebug) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 69
-+; Bound: 81
++; Bound: 77
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -754,10 +754,10 @@ TEST(DiffTest, ExtraIfBlockNoDebug) {
OpDecorate %54 RelaxedPrecision
OpDecorate %55 RelaxedPrecision
OpDecorate %56 RelaxedPrecision
-+OpDecorate %72 RelaxedPrecision
++OpDecorate %70 RelaxedPrecision
OpDecorate %57 RelaxedPrecision
-+OpDecorate %77 RelaxedPrecision
-+OpDecorate %78 RelaxedPrecision
++OpDecorate %75 RelaxedPrecision
++OpDecorate %76 RelaxedPrecision
OpDecorate %58 RelaxedPrecision
OpDecorate %63 RelaxedPrecision
OpDecorate %63 Location 0
@@ -785,7 +785,7 @@ TEST(DiffTest, ExtraIfBlockNoDebug) {
%32 = OpConstant %19 1
%49 = OpConstant %6 10
%52 = OpConstant %6 0.5
-+%76 = OpConstant %6 0.100000001
++%74 = OpConstant %6 0.100000001
%53 = OpConstant %6 0.699999988
%61 = OpTypeVector %6 4
%62 = OpTypePointer Output %61
@@ -841,20 +841,20 @@ TEST(DiffTest, ExtraIfBlockNoDebug) {
%55 = OpLoad %6 %45
%56 = OpFMul %6 %55 %54
OpStore %45 %56
-+%71 = OpAccessChain %21 %18 %32
-+%72 = OpLoad %15 %71
-+%73 = OpINotEqual %25 %72 %24
-+OpSelectionMerge %75 None
-+OpBranchConditional %73 %74 %75
-+%74 = OpLabel
++%69 = OpAccessChain %21 %18 %32
++%70 = OpLoad %15 %69
++%71 = OpINotEqual %25 %70 %24
++OpSelectionMerge %73 None
++OpBranchConditional %71 %72 %73
++%72 = OpLabel
%57 = OpLoad %6 %45
-+%77 = OpFSub %6 %57 %76
-+OpStore %45 %77
-+OpBranch %75
-+%75 = OpLabel
-+%78 = OpLoad %6 %45
++%75 = OpFSub %6 %57 %74
++OpStore %45 %75
++OpBranch %73
++%73 = OpLabel
++%76 = OpLoad %6 %45
-%58 = OpExtInst %6 %1 Exp %57
-+%58 = OpExtInst %6 %1 Exp %78
++%58 = OpExtInst %6 %1 Exp %76
OpReturnValue %58
OpFunctionEnd
)";
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/int_vs_uint_constants_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/int_vs_uint_constants_autogen.cpp
index 187722e89..11bb81179 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/int_vs_uint_constants_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/int_vs_uint_constants_autogen.cpp
@@ -371,10 +371,10 @@ TEST(DiffTest, IntVsUintConstantsDumpIds) {
3 -> 16 [TypePointer]
4 -> 17 [Variable]
5 -> 8 [TypeInt]
- 8 -> 23 [TypeVector]
+ 8 -> 21 [TypeVector]
13 -> 19 [TypePointer]
- 15 -> 29 [Constant]
- 16 -> 30 [TypeArray]
+ 15 -> 22 [Constant]
+ 16 -> 23 [TypeArray]
17 -> 11 [TypeStruct]
18 -> 12 [TypePointer]
19 -> 13 [Variable]
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/multiple_same_entry_points_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/multiple_same_entry_points_autogen.cpp
index 9d011661c..00bee6be3 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/multiple_same_entry_points_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/multiple_same_entry_points_autogen.cpp
@@ -125,9 +125,8 @@ TEST(DiffTest, MultipleSameEntryPoints) {
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
--OpEntryPoint Vertex %12 "main2" %13 %14 %15
+ OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
@@ -257,9 +256,8 @@ TEST(DiffTest, MultipleSameEntryPointsNoDebug) {
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
--OpEntryPoint Vertex %12 "main2" %13 %14 %15
+ OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpDecorate %8 Location 0
OpDecorate %10 Location 0
@@ -304,9 +302,8 @@ TEST(DiffTest, MultipleSameEntryPointsDumpIds) {
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
-+OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpEntryPoint Vertex %4 "main1" %8 %10
--OpEntryPoint Vertex %12 "main2" %13 %14 %15
+ OpEntryPoint Vertex %12 "main2" %13 %14 %15
OpSource ESSL 310
OpName %4 "main1"
OpName %12 "main2"
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_autogen.cpp
new file mode 100644
index 000000000..5507def64
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_autogen.cpp
@@ -0,0 +1,148 @@
+// GENERATED FILE - DO NOT EDIT.
+// Generated by generate_tests.py
+//
+// Copyright (c) 2022 Google LLC.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "../diff_test_utils.h"
+
+#include "gtest/gtest.h"
+
+namespace spvtools {
+namespace diff {
+namespace {
+
+// Test that OpTypeAccelerationStructureNV and OpTypeRayQueryKHR are
+// matched.
+constexpr char kSrc[] = R"(OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd)";
+constexpr char kDst[] = R"(; SPIR-V
+; Version: 1.4
+; Generator: rspirv
+; Bound: 95
+OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+TEST(DiffTest, RayQueryTypes) {
+ constexpr char kDiff[] = R"( ; SPIR-V
+ ; Version: 1.6
+ ; Generator: Khronos SPIR-V Tools Assembler; 0
+ ; Bound: 45
+ ; Schema: 0
+ OpCapability RayQueryKHR
+ OpCapability Shader
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %43 "main"
+ OpExecutionMode %43 LocalSize 1 1 1
+ %2 = OpTypeVoid
+ %3 = OpTypeAccelerationStructureKHR
+ %13 = OpTypeRayQueryKHR
+ %44 = OpTypeFunction %2
+ %43 = OpFunction %2 None %44
+ %42 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ Options options;
+ DoStringDiffTest(kSrc, kDst, kDiff, options);
+}
+
+TEST(DiffTest, RayQueryTypesNoDebug) {
+ constexpr char kSrcNoDebug[] = R"(OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+ constexpr char kDstNoDebug[] = R"(; SPIR-V
+; Version: 1.4
+; Generator: rspirv
+; Bound: 95
+OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+ constexpr char kDiff[] = R"( ; SPIR-V
+ ; Version: 1.6
+ ; Generator: Khronos SPIR-V Tools Assembler; 0
+ ; Bound: 45
+ ; Schema: 0
+ OpCapability RayQueryKHR
+ OpCapability Shader
+ OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %43 "main"
+ OpExecutionMode %43 LocalSize 1 1 1
+ %2 = OpTypeVoid
+ %3 = OpTypeAccelerationStructureKHR
+ %13 = OpTypeRayQueryKHR
+ %44 = OpTypeFunction %2
+ %43 = OpFunction %2 None %44
+ %42 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+ Options options;
+ DoStringDiffTest(kSrcNoDebug, kDstNoDebug, kDiff, options);
+}
+
+} // namespace
+} // namespace diff
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_dst.spvasm b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_dst.spvasm
new file mode 100644
index 000000000..5f8be53d4
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_dst.spvasm
@@ -0,0 +1,18 @@
+; SPIR-V
+; Version: 1.4
+; Generator: rspirv
+; Bound: 95
+OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_src.spvasm b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_src.spvasm
new file mode 100644
index 000000000..0b64015b5
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/ray_query_types_src.spvasm
@@ -0,0 +1,16 @@
+;; Test that OpTypeAccelerationStructureNV and OpTypeRayQueryKHR are
+;; matched.
+OpCapability RayQueryKHR
+OpCapability Shader
+OpExtension "SPV_KHR_ray_query"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %43 "main"
+OpExecutionMode %43 LocalSize 1 1 1
+%2 = OpTypeVoid
+%3 = OpTypeAccelerationStructureNV
+%13 = OpTypeRayQueryKHR
+%44 = OpTypeFunction %2
+%43 = OpFunction %2 None %44
+%42 = OpLabel
+OpReturn
+OpFunctionEnd
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/reordered_if_blocks_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/reordered_if_blocks_autogen.cpp
index 0788199f9..3abaf40de 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/reordered_if_blocks_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/reordered_if_blocks_autogen.cpp
@@ -203,8 +203,7 @@ TEST(DiffTest, ReorderedIfBlocks) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 46
-+; Bound: 47
+ ; Bound: 46
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -471,8 +470,7 @@ TEST(DiffTest, ReorderedIfBlocksNoDebug) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 46
-+; Bound: 47
+ ; Bound: 46
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/reordered_switch_blocks_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/reordered_switch_blocks_autogen.cpp
index c0ba48d1e..ade5350e7 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/reordered_switch_blocks_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/reordered_switch_blocks_autogen.cpp
@@ -212,8 +212,7 @@ TEST(DiffTest, ReorderedSwitchBlocks) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 58
-+; Bound: 62
+ ; Bound: 58
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
@@ -485,8 +484,7 @@ TEST(DiffTest, ReorderedSwitchBlocksNoDebug) {
constexpr char kDiff[] = R"( ; SPIR-V
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
--; Bound: 58
-+; Bound: 62
+ ; Bound: 58
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
diff --git a/third_party/SPIRV-Tools/test/diff/diff_files/spec_constant_array_size_autogen.cpp b/third_party/SPIRV-Tools/test/diff/diff_files/spec_constant_array_size_autogen.cpp
index 1962d27e7..98ad07274 100644
--- a/third_party/SPIRV-Tools/test/diff/diff_files/spec_constant_array_size_autogen.cpp
+++ b/third_party/SPIRV-Tools/test/diff/diff_files/spec_constant_array_size_autogen.cpp
@@ -125,7 +125,7 @@ TEST(DiffTest, SpecConstantArraySize) {
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 36
++; Bound: 29
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
@@ -140,7 +140,7 @@ TEST(DiffTest, SpecConstantArraySize) {
OpName %19 ""
OpName %22 "main"
OpDecorate %4 Location 0
-+OpDecorate %34 SpecId 4
++OpDecorate %27 SpecId 4
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
@@ -153,10 +153,10 @@ TEST(DiffTest, SpecConstantArraySize) {
%8 = OpTypeVector %5 4
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-+%34 = OpSpecConstant %5 8
-+%35 = OpTypeArray %1 %34
++%27 = OpSpecConstant %5 8
++%28 = OpTypeArray %1 %27
-%17 = OpTypeStruct %2 %1 %16 %16
-+%17 = OpTypeStruct %2 %1 %35 %35
++%17 = OpTypeStruct %2 %1 %28 %28
%20 = OpTypeVoid
%25 = OpConstant %5 0
%3 = OpTypePointer Input %2
@@ -261,14 +261,14 @@ OpFunctionEnd
; Version: 1.6
; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 27
-+; Bound: 36
++; Bound: 29
; Schema: 0
OpCapability Shader
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %22 "main" %4 %19
OpSource GLSL 450
OpDecorate %4 Location 0
-+OpDecorate %34 SpecId 4
++OpDecorate %27 SpecId 4
OpMemberDecorate %17 1 RelaxedPrecision
OpMemberDecorate %17 0 BuiltIn Position
OpMemberDecorate %17 1 BuiltIn PointSize
@@ -281,10 +281,10 @@ OpFunctionEnd
%8 = OpTypeVector %5 4
-%15 = OpConstant %5 8
-%16 = OpTypeArray %1 %15
-+%34 = OpSpecConstant %5 8
-+%35 = OpTypeArray %1 %34
++%27 = OpSpecConstant %5 8
++%28 = OpTypeArray %1 %27
-%17 = OpTypeStruct %2 %1 %16 %16
-+%17 = OpTypeStruct %2 %1 %35 %35
++%17 = OpTypeStruct %2 %1 %28 %28
%20 = OpTypeVoid
%25 = OpConstant %5 0
%3 = OpTypePointer Input %2
diff --git a/third_party/SPIRV-Tools/test/enum_set_test.cpp b/third_party/SPIRV-Tools/test/enum_set_test.cpp
index 1f727158e..11105f991 100644
--- a/third_party/SPIRV-Tools/test/enum_set_test.cpp
+++ b/third_party/SPIRV-Tools/test/enum_set_test.cpp
@@ -12,12 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "source/enum_set.h"
+
#include <algorithm>
+#include <array>
+#include <random>
#include <utility>
#include <vector>
#include "gmock/gmock.h"
-#include "source/enum_set.h"
#include "test/unit_spirv.h"
namespace spvtools {
@@ -25,208 +28,800 @@ namespace {
using spvtest::ElementsIn;
using ::testing::Eq;
+using ::testing::Values;
using ::testing::ValuesIn;
+enum class TestEnum : uint32_t {
+ ZERO = 0,
+ ONE = 1,
+ TWO = 2,
+ THREE = 3,
+ FOUR = 4,
+ FIVE = 5,
+ EIGHT = 8,
+ TWENTY = 20,
+ TWENTY_FOUR = 24,
+ THIRTY = 30,
+ ONE_HUNDRED = 100,
+ ONE_HUNDRED_FIFTY = 150,
+ TWO_HUNDRED = 200,
+ THREE_HUNDRED = 300,
+ FOUR_HUNDRED = 400,
+ FIVE_HUNDRED = 500,
+ SIX_HUNDRED = 600,
+};
+
+constexpr std::array kCapabilities{
+ spv::Capability::Matrix,
+ spv::Capability::Shader,
+ spv::Capability::Geometry,
+ spv::Capability::Tessellation,
+ spv::Capability::Addresses,
+ spv::Capability::Linkage,
+ spv::Capability::Kernel,
+ spv::Capability::Vector16,
+ spv::Capability::Float16Buffer,
+ spv::Capability::Float16,
+ spv::Capability::Float64,
+ spv::Capability::Int64,
+ spv::Capability::Int64Atomics,
+ spv::Capability::ImageBasic,
+ spv::Capability::ImageReadWrite,
+ spv::Capability::ImageMipmap,
+ spv::Capability::Pipes,
+ spv::Capability::Groups,
+ spv::Capability::DeviceEnqueue,
+ spv::Capability::LiteralSampler,
+ spv::Capability::AtomicStorage,
+ spv::Capability::Int16,
+ spv::Capability::TessellationPointSize,
+ spv::Capability::GeometryPointSize,
+ spv::Capability::ImageGatherExtended,
+ spv::Capability::StorageImageMultisample,
+ spv::Capability::UniformBufferArrayDynamicIndexing,
+ spv::Capability::SampledImageArrayDynamicIndexing,
+ spv::Capability::StorageBufferArrayDynamicIndexing,
+ spv::Capability::StorageImageArrayDynamicIndexing,
+ spv::Capability::ClipDistance,
+ spv::Capability::CullDistance,
+ spv::Capability::ImageCubeArray,
+ spv::Capability::SampleRateShading,
+ spv::Capability::ImageRect,
+ spv::Capability::SampledRect,
+ spv::Capability::GenericPointer,
+ spv::Capability::Int8,
+ spv::Capability::InputAttachment,
+ spv::Capability::SparseResidency,
+ spv::Capability::MinLod,
+ spv::Capability::Sampled1D,
+ spv::Capability::Image1D,
+ spv::Capability::SampledCubeArray,
+ spv::Capability::SampledBuffer,
+ spv::Capability::ImageBuffer,
+ spv::Capability::ImageMSArray,
+ spv::Capability::StorageImageExtendedFormats,
+ spv::Capability::ImageQuery,
+ spv::Capability::DerivativeControl,
+ spv::Capability::InterpolationFunction,
+ spv::Capability::TransformFeedback,
+ spv::Capability::GeometryStreams,
+ spv::Capability::StorageImageReadWithoutFormat,
+ spv::Capability::StorageImageWriteWithoutFormat,
+ spv::Capability::MultiViewport,
+ spv::Capability::SubgroupDispatch,
+ spv::Capability::NamedBarrier,
+ spv::Capability::PipeStorage,
+ spv::Capability::GroupNonUniform,
+ spv::Capability::GroupNonUniformVote,
+ spv::Capability::GroupNonUniformArithmetic,
+ spv::Capability::GroupNonUniformBallot,
+ spv::Capability::GroupNonUniformShuffle,
+ spv::Capability::GroupNonUniformShuffleRelative,
+ spv::Capability::GroupNonUniformClustered,
+ spv::Capability::GroupNonUniformQuad,
+ spv::Capability::ShaderLayer,
+ spv::Capability::ShaderViewportIndex,
+ spv::Capability::UniformDecoration,
+ spv::Capability::CoreBuiltinsARM,
+ spv::Capability::FragmentShadingRateKHR,
+ spv::Capability::SubgroupBallotKHR,
+ spv::Capability::DrawParameters,
+ spv::Capability::WorkgroupMemoryExplicitLayoutKHR,
+ spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR,
+ spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR,
+ spv::Capability::SubgroupVoteKHR,
+ spv::Capability::StorageBuffer16BitAccess,
+ spv::Capability::StorageUniformBufferBlock16,
+ spv::Capability::StorageUniform16,
+ spv::Capability::UniformAndStorageBuffer16BitAccess,
+ spv::Capability::StoragePushConstant16,
+ spv::Capability::StorageInputOutput16,
+ spv::Capability::DeviceGroup,
+ spv::Capability::MultiView,
+ spv::Capability::VariablePointersStorageBuffer,
+ spv::Capability::VariablePointers,
+ spv::Capability::AtomicStorageOps,
+ spv::Capability::SampleMaskPostDepthCoverage,
+ spv::Capability::StorageBuffer8BitAccess,
+ spv::Capability::UniformAndStorageBuffer8BitAccess,
+ spv::Capability::StoragePushConstant8,
+ spv::Capability::DenormPreserve,
+ spv::Capability::DenormFlushToZero,
+ spv::Capability::SignedZeroInfNanPreserve,
+ spv::Capability::RoundingModeRTE,
+ spv::Capability::RoundingModeRTZ,
+ spv::Capability::RayQueryProvisionalKHR,
+ spv::Capability::RayQueryKHR,
+ spv::Capability::RayTraversalPrimitiveCullingKHR,
+ spv::Capability::RayTracingKHR,
+ spv::Capability::Float16ImageAMD,
+ spv::Capability::ImageGatherBiasLodAMD,
+ spv::Capability::FragmentMaskAMD,
+ spv::Capability::StencilExportEXT,
+ spv::Capability::ImageReadWriteLodAMD,
+ spv::Capability::Int64ImageEXT,
+ spv::Capability::ShaderClockKHR,
+ spv::Capability::SampleMaskOverrideCoverageNV,
+ spv::Capability::GeometryShaderPassthroughNV,
+ spv::Capability::ShaderViewportIndexLayerEXT,
+ spv::Capability::ShaderViewportIndexLayerNV,
+ spv::Capability::ShaderViewportMaskNV,
+ spv::Capability::ShaderStereoViewNV,
+ spv::Capability::PerViewAttributesNV,
+ spv::Capability::FragmentFullyCoveredEXT,
+ spv::Capability::MeshShadingNV,
+ spv::Capability::ImageFootprintNV,
+ spv::Capability::MeshShadingEXT,
+ spv::Capability::FragmentBarycentricKHR,
+ spv::Capability::FragmentBarycentricNV,
+ spv::Capability::ComputeDerivativeGroupQuadsNV,
+ spv::Capability::FragmentDensityEXT,
+ spv::Capability::ShadingRateNV,
+ spv::Capability::GroupNonUniformPartitionedNV,
+ spv::Capability::ShaderNonUniform,
+ spv::Capability::ShaderNonUniformEXT,
+ spv::Capability::RuntimeDescriptorArray,
+ spv::Capability::RuntimeDescriptorArrayEXT,
+ spv::Capability::InputAttachmentArrayDynamicIndexing,
+ spv::Capability::InputAttachmentArrayDynamicIndexingEXT,
+ spv::Capability::UniformTexelBufferArrayDynamicIndexing,
+ spv::Capability::UniformTexelBufferArrayDynamicIndexingEXT,
+ spv::Capability::StorageTexelBufferArrayDynamicIndexing,
+ spv::Capability::StorageTexelBufferArrayDynamicIndexingEXT,
+ spv::Capability::UniformBufferArrayNonUniformIndexing,
+ spv::Capability::UniformBufferArrayNonUniformIndexingEXT,
+ spv::Capability::SampledImageArrayNonUniformIndexing,
+ spv::Capability::SampledImageArrayNonUniformIndexingEXT,
+ spv::Capability::StorageBufferArrayNonUniformIndexing,
+ spv::Capability::StorageBufferArrayNonUniformIndexingEXT,
+ spv::Capability::StorageImageArrayNonUniformIndexing,
+ spv::Capability::StorageImageArrayNonUniformIndexingEXT,
+ spv::Capability::InputAttachmentArrayNonUniformIndexing,
+ spv::Capability::InputAttachmentArrayNonUniformIndexingEXT,
+ spv::Capability::UniformTexelBufferArrayNonUniformIndexing,
+ spv::Capability::UniformTexelBufferArrayNonUniformIndexingEXT,
+ spv::Capability::StorageTexelBufferArrayNonUniformIndexing,
+ spv::Capability::StorageTexelBufferArrayNonUniformIndexingEXT,
+ spv::Capability::RayTracingNV,
+ spv::Capability::RayTracingMotionBlurNV,
+ spv::Capability::VulkanMemoryModel,
+ spv::Capability::VulkanMemoryModelKHR,
+ spv::Capability::VulkanMemoryModelDeviceScope,
+ spv::Capability::VulkanMemoryModelDeviceScopeKHR,
+ spv::Capability::PhysicalStorageBufferAddresses,
+ spv::Capability::PhysicalStorageBufferAddressesEXT,
+ spv::Capability::ComputeDerivativeGroupLinearNV,
+ spv::Capability::RayTracingProvisionalKHR,
+ spv::Capability::CooperativeMatrixNV,
+ spv::Capability::FragmentShaderSampleInterlockEXT,
+ spv::Capability::FragmentShaderShadingRateInterlockEXT,
+ spv::Capability::ShaderSMBuiltinsNV,
+ spv::Capability::FragmentShaderPixelInterlockEXT,
+ spv::Capability::DemoteToHelperInvocation,
+ spv::Capability::DemoteToHelperInvocationEXT,
+ spv::Capability::RayTracingOpacityMicromapEXT,
+ spv::Capability::ShaderInvocationReorderNV,
+ spv::Capability::BindlessTextureNV,
+ spv::Capability::SubgroupShuffleINTEL,
+ spv::Capability::SubgroupBufferBlockIOINTEL,
+ spv::Capability::SubgroupImageBlockIOINTEL,
+ spv::Capability::SubgroupImageMediaBlockIOINTEL,
+ spv::Capability::RoundToInfinityINTEL,
+ spv::Capability::FloatingPointModeINTEL,
+ spv::Capability::IntegerFunctions2INTEL,
+ spv::Capability::FunctionPointersINTEL,
+ spv::Capability::IndirectReferencesINTEL,
+ spv::Capability::AsmINTEL,
+ spv::Capability::AtomicFloat32MinMaxEXT,
+ spv::Capability::AtomicFloat64MinMaxEXT,
+ spv::Capability::AtomicFloat16MinMaxEXT,
+ spv::Capability::VectorComputeINTEL,
+ spv::Capability::VectorAnyINTEL,
+ spv::Capability::ExpectAssumeKHR,
+ spv::Capability::SubgroupAvcMotionEstimationINTEL,
+ spv::Capability::SubgroupAvcMotionEstimationIntraINTEL,
+ spv::Capability::SubgroupAvcMotionEstimationChromaINTEL,
+ spv::Capability::VariableLengthArrayINTEL,
+ spv::Capability::FunctionFloatControlINTEL,
+ spv::Capability::FPGAMemoryAttributesINTEL,
+ spv::Capability::FPFastMathModeINTEL,
+ spv::Capability::ArbitraryPrecisionIntegersINTEL,
+ spv::Capability::ArbitraryPrecisionFloatingPointINTEL,
+ spv::Capability::UnstructuredLoopControlsINTEL,
+ spv::Capability::FPGALoopControlsINTEL,
+ spv::Capability::KernelAttributesINTEL,
+ spv::Capability::FPGAKernelAttributesINTEL,
+ spv::Capability::FPGAMemoryAccessesINTEL,
+ spv::Capability::FPGAClusterAttributesINTEL,
+ spv::Capability::LoopFuseINTEL,
+ spv::Capability::FPGADSPControlINTEL,
+ spv::Capability::MemoryAccessAliasingINTEL,
+ spv::Capability::FPGAInvocationPipeliningAttributesINTEL,
+ spv::Capability::FPGABufferLocationINTEL,
+ spv::Capability::ArbitraryPrecisionFixedPointINTEL,
+ spv::Capability::USMStorageClassesINTEL,
+ spv::Capability::RuntimeAlignedAttributeINTEL,
+ spv::Capability::IOPipesINTEL,
+ spv::Capability::BlockingPipesINTEL,
+ spv::Capability::FPGARegINTEL,
+ spv::Capability::DotProductInputAll,
+ spv::Capability::DotProductInputAllKHR,
+ spv::Capability::DotProductInput4x8Bit,
+ spv::Capability::DotProductInput4x8BitKHR,
+ spv::Capability::DotProductInput4x8BitPacked,
+ spv::Capability::DotProductInput4x8BitPackedKHR,
+ spv::Capability::DotProduct,
+ spv::Capability::DotProductKHR,
+ spv::Capability::RayCullMaskKHR,
+ spv::Capability::BitInstructions,
+ spv::Capability::GroupNonUniformRotateKHR,
+ spv::Capability::AtomicFloat32AddEXT,
+ spv::Capability::AtomicFloat64AddEXT,
+ spv::Capability::LongCompositesINTEL,
+ spv::Capability::OptNoneINTEL,
+ spv::Capability::AtomicFloat16AddEXT,
+ spv::Capability::DebugInfoModuleINTEL,
+ spv::Capability::SplitBarrierINTEL,
+ spv::Capability::GroupUniformArithmeticKHR,
+ spv::Capability::Max,
+};
+
+namespace {
+std::vector<TestEnum> enumerateValuesFromToWithStep(size_t start, size_t end,
+ size_t step) {
+ assert(end > start && "end > start");
+ std::vector<TestEnum> orderedValues;
+ for (size_t i = start; i < end; i += step) {
+ orderedValues.push_back(static_cast<TestEnum>(i));
+ }
+ return orderedValues;
+}
+
+EnumSet<TestEnum> createSetUnorderedInsertion(
+ const std::vector<TestEnum>& values) {
+ std::vector shuffledValues(values.cbegin(), values.cend());
+ std::mt19937 rng(0);
+ std::shuffle(shuffledValues.begin(), shuffledValues.end(), rng);
+ EnumSet<TestEnum> set;
+ for (auto value : shuffledValues) {
+ set.insert(value);
+ }
+ return set;
+}
+} // namespace
+
TEST(EnumSet, IsEmpty1) {
- EnumSet<uint32_t> set;
- EXPECT_TRUE(set.IsEmpty());
- set.Add(0);
- EXPECT_FALSE(set.IsEmpty());
+ EnumSet<TestEnum> set;
+ EXPECT_TRUE(set.empty());
+ set.insert(TestEnum::ZERO);
+ EXPECT_FALSE(set.empty());
}
TEST(EnumSet, IsEmpty2) {
- EnumSet<uint32_t> set;
- EXPECT_TRUE(set.IsEmpty());
- set.Add(150);
- EXPECT_FALSE(set.IsEmpty());
+ EnumSet<TestEnum> set;
+ EXPECT_TRUE(set.empty());
+ set.insert(TestEnum::ONE_HUNDRED_FIFTY);
+ EXPECT_FALSE(set.empty());
}
TEST(EnumSet, IsEmpty3) {
- EnumSet<uint32_t> set(4);
- EXPECT_FALSE(set.IsEmpty());
+ EnumSet<TestEnum> set(TestEnum::FOUR);
+ EXPECT_FALSE(set.empty());
}
TEST(EnumSet, IsEmpty4) {
- EnumSet<uint32_t> set(300);
- EXPECT_FALSE(set.IsEmpty());
+ EnumSet<TestEnum> set(TestEnum::THREE_HUNDRED);
+ EXPECT_FALSE(set.empty());
}
TEST(EnumSetHasAnyOf, EmptySetEmptyQuery) {
- const EnumSet<uint32_t> set;
- const EnumSet<uint32_t> empty;
+ const EnumSet<TestEnum> set;
+ const EnumSet<TestEnum> empty;
EXPECT_TRUE(set.HasAnyOf(empty));
- EXPECT_TRUE(EnumSet<uint32_t>().HasAnyOf(EnumSet<uint32_t>()));
+ EXPECT_TRUE(EnumSet<TestEnum>().HasAnyOf(EnumSet<TestEnum>()));
}
TEST(EnumSetHasAnyOf, MaskSetEmptyQuery) {
- EnumSet<uint32_t> set;
- const EnumSet<uint32_t> empty;
- set.Add(5);
- set.Add(8);
+ EnumSet<TestEnum> set;
+ const EnumSet<TestEnum> empty;
+ set.insert(TestEnum::FIVE);
+ set.insert(TestEnum::EIGHT);
EXPECT_TRUE(set.HasAnyOf(empty));
}
TEST(EnumSetHasAnyOf, OverflowSetEmptyQuery) {
- EnumSet<uint32_t> set;
- const EnumSet<uint32_t> empty;
- set.Add(200);
- set.Add(300);
+ EnumSet<TestEnum> set;
+ const EnumSet<TestEnum> empty;
+ set.insert(TestEnum::TWO_HUNDRED);
+ set.insert(TestEnum::THREE_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(empty));
}
TEST(EnumSetHasAnyOf, EmptyQuery) {
- EnumSet<uint32_t> set;
- const EnumSet<uint32_t> empty;
- set.Add(5);
- set.Add(8);
- set.Add(200);
- set.Add(300);
+ EnumSet<TestEnum> set;
+ const EnumSet<TestEnum> empty;
+ set.insert(TestEnum::FIVE);
+ set.insert(TestEnum::EIGHT);
+ set.insert(TestEnum::TWO_HUNDRED);
+ set.insert(TestEnum::THREE_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(empty));
}
TEST(EnumSetHasAnyOf, EmptyQueryAlwaysTrue) {
- EnumSet<uint32_t> set;
- const EnumSet<uint32_t> empty;
+ EnumSet<TestEnum> set;
+ const EnumSet<TestEnum> empty;
EXPECT_TRUE(set.HasAnyOf(empty));
- set.Add(5);
+ set.insert(TestEnum::FIVE);
EXPECT_TRUE(set.HasAnyOf(empty));
- EXPECT_TRUE(EnumSet<uint32_t>(100).HasAnyOf(EnumSet<uint32_t>()));
+ EXPECT_TRUE(
+ EnumSet<TestEnum>(TestEnum::ONE_HUNDRED).HasAnyOf(EnumSet<TestEnum>()));
}
TEST(EnumSetHasAnyOf, ReflexiveMask) {
- EnumSet<uint32_t> set(3);
- set.Add(24);
- set.Add(30);
+ EnumSet<TestEnum> set(TestEnum::THREE);
+ set.insert(TestEnum::TWENTY_FOUR);
+ set.insert(TestEnum::THIRTY);
EXPECT_TRUE(set.HasAnyOf(set));
}
TEST(EnumSetHasAnyOf, ReflexiveOverflow) {
- EnumSet<uint32_t> set(200);
- set.Add(300);
- set.Add(400);
+ EnumSet<TestEnum> set(TestEnum::TWO_HUNDRED);
+ set.insert(TestEnum::TWO_HUNDRED);
+ set.insert(TestEnum::FOUR_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(set));
}
TEST(EnumSetHasAnyOf, Reflexive) {
- EnumSet<uint32_t> set(3);
- set.Add(24);
- set.Add(300);
- set.Add(400);
+ EnumSet<TestEnum> set(TestEnum::THREE);
+ set.insert(TestEnum::TWENTY_FOUR);
+ set.insert(TestEnum::THREE_HUNDRED);
+ set.insert(TestEnum::FOUR_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(set));
}
TEST(EnumSetHasAnyOf, EmptySetHasNone) {
- EnumSet<uint32_t> set;
- EnumSet<uint32_t> items;
+ EnumSet<TestEnum> set;
+ EnumSet<TestEnum> items;
for (uint32_t i = 0; i < 200; ++i) {
- items.Add(i);
+ TestEnum enumValue = static_cast<TestEnum>(i);
+ items.insert(enumValue);
EXPECT_FALSE(set.HasAnyOf(items));
- EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(i)));
+ EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(enumValue)));
}
}
TEST(EnumSetHasAnyOf, MaskSetMaskQuery) {
- EnumSet<uint32_t> set(0);
- EnumSet<uint32_t> items(1);
+ EnumSet<TestEnum> set(TestEnum::ZERO);
+ EnumSet<TestEnum> items(TestEnum::ONE);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(2);
- items.Add(3);
+ set.insert(TestEnum::TWO);
+ items.insert(TestEnum::THREE);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(3);
+ set.insert(TestEnum::THREE);
EXPECT_TRUE(set.HasAnyOf(items));
- set.Add(4);
+ set.insert(TestEnum::FOUR);
EXPECT_TRUE(set.HasAnyOf(items));
}
TEST(EnumSetHasAnyOf, OverflowSetOverflowQuery) {
- EnumSet<uint32_t> set(100);
- EnumSet<uint32_t> items(200);
+ EnumSet<TestEnum> set(TestEnum::ONE_HUNDRED);
+ EnumSet<TestEnum> items(TestEnum::TWO_HUNDRED);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(300);
- items.Add(400);
+ set.insert(TestEnum::THREE_HUNDRED);
+ items.insert(TestEnum::FOUR_HUNDRED);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(200);
+ set.insert(TestEnum::TWO_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(items));
- set.Add(500);
+ set.insert(TestEnum::FIVE_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(items));
}
TEST(EnumSetHasAnyOf, GeneralCase) {
- EnumSet<uint32_t> set(0);
- EnumSet<uint32_t> items(100);
+ EnumSet<TestEnum> set(TestEnum::ZERO);
+ EnumSet<TestEnum> items(TestEnum::ONE_HUNDRED);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(300);
- items.Add(4);
+ set.insert(TestEnum::THREE_HUNDRED);
+ items.insert(TestEnum::FOUR);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(5);
- items.Add(500);
+ set.insert(TestEnum::FIVE);
+ items.insert(TestEnum::FIVE_HUNDRED);
EXPECT_FALSE(set.HasAnyOf(items));
- set.Add(500);
+ set.insert(TestEnum::FIVE_HUNDRED);
EXPECT_TRUE(set.HasAnyOf(items));
- EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(20)));
- EXPECT_FALSE(set.HasAnyOf(EnumSet<uint32_t>(600)));
- EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(5)));
- EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(300)));
- EXPECT_TRUE(set.HasAnyOf(EnumSet<uint32_t>(0)));
+ EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::TWENTY)));
+ EXPECT_FALSE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::SIX_HUNDRED)));
+ EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::FIVE)));
+ EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::THREE_HUNDRED)));
+ EXPECT_TRUE(set.HasAnyOf(EnumSet<TestEnum>(TestEnum::ZERO)));
}
TEST(EnumSet, DefaultIsEmpty) {
- EnumSet<uint32_t> set;
+ EnumSet<TestEnum> set;
for (uint32_t i = 0; i < 1000; ++i) {
- EXPECT_FALSE(set.Contains(i));
+ EXPECT_FALSE(set.contains(static_cast<TestEnum>(i)));
+ }
+}
+
+TEST(EnumSet, EqualityCompareEmpty) {
+ EnumSet<TestEnum> set1;
+ EnumSet<TestEnum> set2;
+
+ EXPECT_TRUE(set1 == set2);
+ EXPECT_FALSE(set1 != set2);
+}
+
+TEST(EnumSet, EqualityCompareSame) {
+ EnumSet<TestEnum> set1;
+ EnumSet<TestEnum> set2;
+
+ set1.insert(TestEnum::ONE);
+ set1.insert(TestEnum::TWENTY);
+ set2.insert(TestEnum::TWENTY);
+ set2.insert(TestEnum::ONE);
+
+ EXPECT_TRUE(set1 == set2);
+ EXPECT_FALSE(set1 != set2);
+}
+
+TEST(EnumSet, EqualityCompareDifferent) {
+ EnumSet<TestEnum> set1;
+ EnumSet<TestEnum> set2;
+
+ set1.insert(TestEnum::ONE);
+ set1.insert(TestEnum::TWENTY);
+ set2.insert(TestEnum::FIVE);
+ set2.insert(TestEnum::ONE);
+
+ EXPECT_FALSE(set1 == set2);
+ EXPECT_TRUE(set1 != set2);
+}
+
+TEST(EnumSet, ConstructFromIterators) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
+ EnumSet<TestEnum> set1 = createSetUnorderedInsertion(orderedValues);
+
+ EnumSet<TestEnum> set2(orderedValues.cbegin(), orderedValues.cend());
+
+ EXPECT_EQ(set1, set2);
+}
+
+TEST(EnumSet, InsertUsingIteratorRange) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
+ EnumSet<TestEnum> set1 = createSetUnorderedInsertion(orderedValues);
+
+ EnumSet<TestEnum> set2;
+ set2.insert(orderedValues.cbegin(), orderedValues.cend());
+
+ EXPECT_EQ(set1, set2);
+}
+
+TEST(CapabilitySet, RangeBasedLoopOrderIsEnumOrder) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 2, /* step= */ 1);
+ auto set = createSetUnorderedInsertion(orderedValues);
+
+ size_t index = 0;
+ for (auto value : set) {
+ ASSERT_THAT(value, Eq(orderedValues[index]));
+ index++;
}
}
TEST(CapabilitySet, ConstructSingleMemberMatrix) {
CapabilitySet s(spv::Capability::Matrix);
- EXPECT_TRUE(s.Contains(spv::Capability::Matrix));
- EXPECT_FALSE(s.Contains(spv::Capability::Shader));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(1000)));
+ EXPECT_TRUE(s.contains(spv::Capability::Matrix));
+ EXPECT_FALSE(s.contains(spv::Capability::Shader));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
}
TEST(CapabilitySet, ConstructSingleMemberMaxInMask) {
CapabilitySet s(static_cast<spv::Capability>(63));
- EXPECT_FALSE(s.Contains(spv::Capability::Matrix));
- EXPECT_FALSE(s.Contains(spv::Capability::Shader));
- EXPECT_TRUE(s.Contains(static_cast<spv::Capability>(63)));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(64)));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(1000)));
+ EXPECT_FALSE(s.contains(spv::Capability::Matrix));
+ EXPECT_FALSE(s.contains(spv::Capability::Shader));
+ EXPECT_TRUE(s.contains(static_cast<spv::Capability>(63)));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(64)));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
}
TEST(CapabilitySet, ConstructSingleMemberMinOverflow) {
// Check the first one that forces overflow beyond the mask.
CapabilitySet s(static_cast<spv::Capability>(64));
- EXPECT_FALSE(s.Contains(spv::Capability::Matrix));
- EXPECT_FALSE(s.Contains(spv::Capability::Shader));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(63)));
- EXPECT_TRUE(s.Contains(static_cast<spv::Capability>(64)));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(1000)));
+ EXPECT_FALSE(s.contains(spv::Capability::Matrix));
+ EXPECT_FALSE(s.contains(spv::Capability::Shader));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(63)));
+ EXPECT_TRUE(s.contains(static_cast<spv::Capability>(64)));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
}
TEST(CapabilitySet, ConstructSingleMemberMaxOverflow) {
// Check the max 32-bit signed int.
CapabilitySet s(static_cast<spv::Capability>(0x7fffffffu));
- EXPECT_FALSE(s.Contains(spv::Capability::Matrix));
- EXPECT_FALSE(s.Contains(spv::Capability::Shader));
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(1000)));
- EXPECT_TRUE(s.Contains(static_cast<spv::Capability>(0x7fffffffu)));
+ EXPECT_FALSE(s.contains(spv::Capability::Matrix));
+ EXPECT_FALSE(s.contains(spv::Capability::Shader));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(1000)));
+ EXPECT_TRUE(s.contains(static_cast<spv::Capability>(0x7fffffffu)));
}
TEST(CapabilitySet, AddEnum) {
CapabilitySet s(spv::Capability::Shader);
- s.Add(spv::Capability::Kernel);
- s.Add(static_cast<spv::Capability>(42));
- EXPECT_FALSE(s.Contains(spv::Capability::Matrix));
- EXPECT_TRUE(s.Contains(spv::Capability::Shader));
- EXPECT_TRUE(s.Contains(spv::Capability::Kernel));
- EXPECT_TRUE(s.Contains(static_cast<spv::Capability>(42)));
+ s.insert(spv::Capability::Kernel);
+ s.insert(static_cast<spv::Capability>(42));
+ EXPECT_FALSE(s.contains(spv::Capability::Matrix));
+ EXPECT_TRUE(s.contains(spv::Capability::Shader));
+ EXPECT_TRUE(s.contains(spv::Capability::Kernel));
+ EXPECT_TRUE(s.contains(static_cast<spv::Capability>(42)));
+}
+
+TEST(CapabilitySet, InsertReturnsIteratorToInserted) {
+ CapabilitySet set;
+
+ auto[it, inserted] = set.insert(spv::Capability::Kernel);
+
+ EXPECT_TRUE(inserted);
+ EXPECT_EQ(*it, spv::Capability::Kernel);
+}
+
+TEST(CapabilitySet, InsertReturnsIteratorToElementOnDoubleInsertion) {
+ CapabilitySet set;
+ EXPECT_FALSE(set.contains(spv::Capability::Shader));
+ {
+ auto[it, inserted] = set.insert(spv::Capability::Shader);
+ EXPECT_TRUE(inserted);
+ EXPECT_EQ(*it, spv::Capability::Shader);
+ }
+ EXPECT_TRUE(set.contains(spv::Capability::Shader));
+
+ auto[it, inserted] = set.insert(spv::Capability::Shader);
+
+ EXPECT_FALSE(inserted);
+ EXPECT_EQ(*it, spv::Capability::Shader);
+ EXPECT_TRUE(set.contains(spv::Capability::Shader));
+}
+
+TEST(CapabilitySet, InsertWithHintWorks) {
+ CapabilitySet set;
+ EXPECT_FALSE(set.contains(spv::Capability::Shader));
+
+ auto it = set.insert(set.begin(), spv::Capability::Shader);
+
+ EXPECT_EQ(*it, spv::Capability::Shader);
+ EXPECT_TRUE(set.contains(spv::Capability::Shader));
+}
+
+TEST(CapabilitySet, InsertWithEndHintWorks) {
+ CapabilitySet set;
+ EXPECT_FALSE(set.contains(spv::Capability::Shader));
+
+ auto it = set.insert(set.end(), spv::Capability::Shader);
+
+ EXPECT_EQ(*it, spv::Capability::Shader);
+ EXPECT_TRUE(set.contains(spv::Capability::Shader));
+}
+
+TEST(CapabilitySet, IteratorCanBeCopied) {
+ CapabilitySet set;
+ set.insert(spv::Capability::Matrix);
+ set.insert(spv::Capability::Shader);
+ set.insert(spv::Capability::Geometry);
+ set.insert(spv::Capability::Float64);
+ set.insert(spv::Capability::Float16);
+
+ auto a = set.begin();
+ ++a;
+ auto b = a;
+
+ EXPECT_EQ(*b, *a);
+ ++b;
+ EXPECT_NE(*b, *a);
+
+ ++a;
+ EXPECT_EQ(*b, *a);
+
+ ++a;
+ EXPECT_NE(*b, *a);
+}
+
+TEST(CapabilitySet, IteratorBeginToEndPostfix) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1);
+ auto set = createSetUnorderedInsertion(orderedValues);
+
+ size_t index = 0;
+ for (auto it = set.cbegin(); it != set.cend(); it++, index++) {
+ EXPECT_EQ(*it, orderedValues[index]);
+ }
+}
+
+TEST(CapabilitySet, IteratorBeginToEndPrefix) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 1);
+ auto set = createSetUnorderedInsertion(orderedValues);
+
+ size_t index = 0;
+ for (auto it = set.cbegin(); it != set.cend(); ++it, index++) {
+ EXPECT_EQ(*it, orderedValues[index]);
+ }
+}
+
+TEST(CapabilitySet, IteratorBeginToEndPrefixStep) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 8);
+ auto set = createSetUnorderedInsertion(orderedValues);
+
+ size_t index = 0;
+ for (auto it = set.cbegin(); it != set.cend(); ++it, index++) {
+ ASSERT_EQ(*it, orderedValues[index]);
+ }
+}
+
+TEST(CapabilitySet, IteratorBeginOnEmpty) {
+ CapabilitySet set;
+
+ auto begin = set.begin();
+ auto end = set.end();
+ ASSERT_EQ(begin, end);
+}
+
+TEST(CapabilitySet, IteratorBeginOnSingleNonZeroValue) {
+ CapabilitySet set;
+ set.insert(spv::Capability::Shader);
+
+ auto begin = set.begin();
+ auto end = set.end();
+
+ ASSERT_NE(begin, end);
+ ASSERT_EQ(*begin, spv::Capability::Shader);
+}
+
+TEST(CapabilitySet, IteratorForLoopNonZeroValue) {
+ CapabilitySet set;
+ set.insert(spv::Capability::Shader);
+ set.insert(spv::Capability::Tessellation);
+
+ auto begin = set.begin();
+ auto end = set.end();
+
+ ASSERT_NE(begin, end);
+ ASSERT_EQ(*begin, spv::Capability::Shader);
+
+ begin++;
+ ASSERT_NE(begin, end);
+ ASSERT_EQ(*begin, spv::Capability::Tessellation);
+
+ begin++;
+ ASSERT_EQ(begin, end);
+}
+
+TEST(CapabilitySet, IteratorPastEnd) {
+ CapabilitySet set;
+ set.insert(spv::Capability::Shader);
+
+ auto begin = set.begin();
+ auto end = set.end();
+
+ ASSERT_NE(begin, end);
+ ASSERT_EQ(*begin, spv::Capability::Shader);
+
+ begin++;
+ ASSERT_EQ(begin, end);
+
+ begin++;
+ ASSERT_EQ(begin, end);
+}
+
+TEST(CapabilitySet, CompatibleWithSTLFind) {
+ CapabilitySet set;
+ set.insert(spv::Capability::Matrix);
+ set.insert(spv::Capability::Shader);
+ set.insert(spv::Capability::Geometry);
+ set.insert(spv::Capability::Tessellation);
+ set.insert(spv::Capability::Addresses);
+ set.insert(spv::Capability::Linkage);
+ set.insert(spv::Capability::Kernel);
+ set.insert(spv::Capability::Vector16);
+ set.insert(spv::Capability::Float16Buffer);
+ set.insert(spv::Capability::Float64);
+
+ {
+ auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Vector16);
+ ASSERT_NE(it, set.end());
+ ASSERT_EQ(*it, spv::Capability::Vector16);
+ }
+
+ {
+ auto it = std::find(set.cbegin(), set.cend(), spv::Capability::Float16);
+ ASSERT_EQ(it, set.end());
+ }
+}
+
+TEST(CapabilitySet, CompatibleWithSTLForEach) {
+ auto orderedValues = enumerateValuesFromToWithStep(0, 100, /* step= */ 15);
+ auto set = createSetUnorderedInsertion(orderedValues);
+
+ size_t index = 0;
+ std::for_each(set.cbegin(), set.cend(), [&](auto item) {
+ ASSERT_EQ(item, orderedValues[index]);
+ index++;
+ });
}
TEST(CapabilitySet, InitializerListEmpty) {
CapabilitySet s{};
for (uint32_t i = 0; i < 1000; i++) {
- EXPECT_FALSE(s.Contains(static_cast<spv::Capability>(i)));
+ EXPECT_FALSE(s.contains(static_cast<spv::Capability>(i)));
+ }
+}
+
+TEST(CapabilitySet, LargeSetHasInsertedElements) {
+ CapabilitySet set;
+ for (auto c : kCapabilities) {
+ EXPECT_FALSE(set.contains(c));
+ }
+
+ for (auto c : kCapabilities) {
+ set.insert(c);
+ EXPECT_TRUE(set.contains(c));
+ }
+
+ for (auto c : kCapabilities) {
+ EXPECT_TRUE(set.contains(c));
+ }
+}
+
+TEST(CapabilitySet, LargeSetHasUnsortedInsertedElements) {
+ std::vector shuffledCapabilities(kCapabilities.cbegin(),
+ kCapabilities.cend());
+ std::mt19937 rng(0);
+ std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng);
+ CapabilitySet set;
+ for (auto c : shuffledCapabilities) {
+ EXPECT_FALSE(set.contains(c));
+ }
+
+ for (auto c : shuffledCapabilities) {
+ set.insert(c);
+ EXPECT_TRUE(set.contains(c));
+ }
+
+ for (auto c : shuffledCapabilities) {
+ EXPECT_TRUE(set.contains(c));
+ }
+}
+
+TEST(CapabilitySet, LargeSetHasUnsortedRemovedElement) {
+ std::vector shuffledCapabilities(kCapabilities.cbegin(),
+ kCapabilities.cend());
+ std::mt19937 rng(0);
+ std::shuffle(shuffledCapabilities.begin(), shuffledCapabilities.end(), rng);
+ CapabilitySet set;
+ for (auto c : shuffledCapabilities) {
+ set.insert(c);
+ EXPECT_TRUE(set.contains(c));
+ }
+
+ for (auto c : kCapabilities) {
+ set.erase(c);
+ }
+
+ for (auto c : shuffledCapabilities) {
+ EXPECT_FALSE(set.contains(c));
}
}
@@ -287,5 +882,20 @@ INSTANTIATE_TEST_SUITE_P(
static_cast<spv::Capability>(0x7fffffff)}},
}));
+using BoundaryTestWithParam = ::testing::TestWithParam<spv::Capability>;
+
+TEST_P(BoundaryTestWithParam, InsertedContains) {
+ CapabilitySet set;
+ set.insert(GetParam());
+ EXPECT_TRUE(set.contains(GetParam()));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ Samples, BoundaryTestWithParam,
+ Values(static_cast<spv::Capability>(0), static_cast<spv::Capability>(63),
+ static_cast<spv::Capability>(64), static_cast<spv::Capability>(65),
+ static_cast<spv::Capability>(127), static_cast<spv::Capability>(128),
+ static_cast<spv::Capability>(129)));
+
} // namespace
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/fuzz/transformation_add_no_contraction_decoration_test.cpp b/third_party/SPIRV-Tools/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
index 4fc9d2d56..1280b815e 100644
--- a/third_party/SPIRV-Tools/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
+++ b/third_party/SPIRV-Tools/test/fuzz/transformation_add_no_contraction_decoration_test.cpp
@@ -36,7 +36,6 @@ TEST(TransformationAddNoContractionDecorationTest, BasicScenarios) {
OpName %8 "x"
OpName %10 "y"
OpName %14 "i"
- OpDecorate %32 NoContraction
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeFloat 32
@@ -110,9 +109,8 @@ TEST(TransformationAddNoContractionDecorationTest, BasicScenarios) {
ASSERT_FALSE(TransformationAddNoContractionDecoration(24).IsApplicable(
context.get(), transformation_context));
- // It is valid to add NoContraction to each of these ids (and it's fine to
- // have duplicates of the decoration, in the case of 32).
- for (uint32_t result_id : {32u, 32u, 27u, 29u, 39u}) {
+ // It is valid to add NoContraction to each of these ids.
+ for (uint32_t result_id : {32u, 27u, 29u, 39u}) {
TransformationAddNoContractionDecoration transformation(result_id);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
@@ -134,8 +132,6 @@ TEST(TransformationAddNoContractionDecorationTest, BasicScenarios) {
OpName %10 "y"
OpName %14 "i"
OpDecorate %32 NoContraction
- OpDecorate %32 NoContraction
- OpDecorate %32 NoContraction
OpDecorate %27 NoContraction
OpDecorate %29 NoContraction
OpDecorate %39 NoContraction
diff --git a/third_party/SPIRV-Tools/test/fuzz/transformation_add_opphi_synonym_test.cpp b/third_party/SPIRV-Tools/test/fuzz/transformation_add_opphi_synonym_test.cpp
index 4aca30ce6..03fd39a12 100644
--- a/third_party/SPIRV-Tools/test/fuzz/transformation_add_opphi_synonym_test.cpp
+++ b/third_party/SPIRV-Tools/test/fuzz/transformation_add_opphi_synonym_test.cpp
@@ -365,8 +365,7 @@ TEST(TransformationAddOpPhiSynonymTest, VariablePointers) {
MakeSynonymFact(12, 16));
// Remove the VariablePointers capability.
- context.get()->get_feature_mgr()->RemoveCapability(
- spv::Capability::VariablePointers);
+ context.get()->RemoveCapability(spv::Capability::VariablePointers);
// The VariablePointers capability is required to add an OpPhi instruction of
// pointer type.
@@ -374,8 +373,7 @@ TEST(TransformationAddOpPhiSynonymTest, VariablePointers) {
.IsApplicable(context.get(), transformation_context));
// Add the VariablePointers capability back.
- context.get()->get_feature_mgr()->AddCapability(
- spv::Capability::VariablePointers);
+ context.get()->AddCapability(spv::Capability::VariablePointers);
// If the ids have pointer type, the storage class must be Workgroup or
// StorageBuffer, but it is Function in this case.
diff --git a/third_party/SPIRV-Tools/test/fuzz/transformation_add_relaxed_decoration_test.cpp b/third_party/SPIRV-Tools/test/fuzz/transformation_add_relaxed_decoration_test.cpp
index c4408827f..979eeb722 100644
--- a/third_party/SPIRV-Tools/test/fuzz/transformation_add_relaxed_decoration_test.cpp
+++ b/third_party/SPIRV-Tools/test/fuzz/transformation_add_relaxed_decoration_test.cpp
@@ -86,9 +86,8 @@ TEST(TransformationAddRelaxedDecorationTest, BasicScenarios) {
// Invalid: 28 is in a dead block, but returns bool (not numeric).
ASSERT_FALSE(TransformationAddRelaxedDecoration(28).IsApplicable(
context.get(), transformation_context));
- // It is valid to add RelaxedPrecision to 25 (and it's fine to
- // have a duplicate).
- for (uint32_t result_id : {25u, 25u}) {
+ // It is valid to add RelaxedPrecision to 25
+ for (uint32_t result_id : {25u}) {
TransformationAddRelaxedDecoration transformation(result_id);
ASSERT_TRUE(
transformation.IsApplicable(context.get(), transformation_context));
@@ -110,7 +109,6 @@ TEST(TransformationAddRelaxedDecorationTest, BasicScenarios) {
OpName %10 "b"
OpName %14 "c"
OpDecorate %25 RelaxedPrecision
- OpDecorate %25 RelaxedPrecision
%2 = OpTypeVoid
%3 = OpTypeFunction %2
%6 = OpTypeInt 32 1
diff --git a/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_float_test.cpp b/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_float_test.cpp
index 75f37887a..135190acb 100644
--- a/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_float_test.cpp
+++ b/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_float_test.cpp
@@ -74,7 +74,7 @@ TEST(TransformationAddTypeFloatTest, IsApplicable) {
// By default, SPIR-V does not support 64-bit float types.
// Below we add such capability, so the test should now pass.
- context.get()->get_feature_mgr()->AddCapability(spv::Capability::Float64);
+ context.get()->AddCapability(spv::Capability::Float64);
ASSERT_TRUE(TransformationAddTypeFloat(7, 64).IsApplicable(
context.get(), transformation_context));
diff --git a/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_int_test.cpp b/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_int_test.cpp
index b41d42037..e31730cc2 100644
--- a/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_int_test.cpp
+++ b/third_party/SPIRV-Tools/test/fuzz/transformation_add_type_int_test.cpp
@@ -88,13 +88,13 @@ TEST(TransformationAddTypeIntTest, IsApplicable) {
// By default SPIR-V does not support 16-bit integers.
// Below we add such capability, so the test should now be successful.
- context.get()->get_feature_mgr()->AddCapability(spv::Capability::Int16);
+ context.get()->AddCapability(spv::Capability::Int16);
ASSERT_TRUE(TransformationAddTypeInt(7, 16, true)
.IsApplicable(context.get(), transformation_context));
// By default SPIR-V does not support 64-bit integers.
// Below we add such capability, so the test should now pass.
- context.get()->get_feature_mgr()->AddCapability(spv::Capability::Int64);
+ context.get()->AddCapability(spv::Capability::Int64);
ASSERT_TRUE(TransformationAddTypeInt(7, 64, true)
.IsApplicable(context.get(), transformation_context));
diff --git a/third_party/SPIRV-Tools/test/link/binary_version_test.cpp b/third_party/SPIRV-Tools/test/link/binary_version_test.cpp
index 78da1aece..384255a46 100644
--- a/third_party/SPIRV-Tools/test/link/binary_version_test.cpp
+++ b/third_party/SPIRV-Tools/test/link/binary_version_test.cpp
@@ -73,5 +73,21 @@ TEST_F(BinaryVersion, Mismatch) {
"through 1) vs 1.5 (input module 2)."));
}
+TEST_F(BinaryVersion, UseHighest) {
+ // clang-format off
+ spvtest::Binaries binaries = {
+ CreateBinary(SPV_SPIRV_VERSION_WORD(1, 3)),
+ CreateBinary(SPV_SPIRV_VERSION_WORD(1, 5)),
+ };
+ // clang-format on
+ LinkerOptions options;
+ options.SetUseHighestVersion(true);
+ spvtest::Binary linked_binary;
+ ASSERT_EQ(SPV_SUCCESS, Link(binaries, &linked_binary, options))
+ << GetErrorMessage();
+ EXPECT_THAT(GetErrorMessage(), std::string());
+ EXPECT_EQ(SPV_SPIRV_VERSION_WORD(1, 5), linked_binary[1]);
+}
+
} // namespace
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/log_test.cpp b/third_party/SPIRV-Tools/test/log_test.cpp
deleted file mode 100644
index ec66aa1ec..000000000
--- a/third_party/SPIRV-Tools/test/log_test.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2016 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "source/opt/log.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace spvtools {
-namespace {
-
-using ::testing::MatchesRegex;
-
-TEST(Log, Unimplemented) {
- int invocation = 0;
- auto consumer = [&invocation](spv_message_level_t level, const char* source,
- const spv_position_t&, const char* message) {
- ++invocation;
- EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level);
- EXPECT_THAT(source, MatchesRegex(".*log_test.cpp$"));
- EXPECT_STREQ("unimplemented: the-ultimite-feature", message);
- };
-
- SPIRV_UNIMPLEMENTED(consumer, "the-ultimite-feature");
- EXPECT_EQ(1, invocation);
-}
-
-TEST(Log, Unreachable) {
- int invocation = 0;
- auto consumer = [&invocation](spv_message_level_t level, const char* source,
- const spv_position_t&, const char* message) {
- ++invocation;
- EXPECT_EQ(SPV_MSG_INTERNAL_ERROR, level);
- EXPECT_THAT(source, MatchesRegex(".*log_test.cpp$"));
- EXPECT_STREQ("unreachable", message);
- };
-
- SPIRV_UNREACHABLE(consumer);
- EXPECT_EQ(1, invocation);
-}
-
-} // namespace
-} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/operand_capabilities_test.cpp b/third_party/SPIRV-Tools/test/operand_capabilities_test.cpp
index 01b98a63e..53dbe0701 100644
--- a/third_party/SPIRV-Tools/test/operand_capabilities_test.cpp
+++ b/third_party/SPIRV-Tools/test/operand_capabilities_test.cpp
@@ -18,7 +18,12 @@
#include <vector>
#include "gmock/gmock.h"
+#include "source/assembly_grammar.h"
#include "source/enum_set.h"
+#include "source/operand.h"
+#include "source/spirv_target_env.h"
+#include "source/table.h"
+#include "spirv-tools/libspirv.h"
#include "test/unit_spirv.h"
namespace spvtools {
@@ -31,6 +36,25 @@ using ::testing::TestWithParam;
using ::testing::Values;
using ::testing::ValuesIn;
+// Emits a CapabilitySet to the given ostream, returning the ostream.
+inline std::ostream& operator<<(std::ostream& out, const CapabilitySet& cs) {
+ out << "CapabilitySet{";
+ auto ctx = spvContextCreate(SPV_ENV_UNIVERSAL_1_0);
+ spvtools::AssemblyGrammar grammar(ctx);
+ bool first = true;
+ for (auto c : cs) {
+ if (!first) {
+ out << " ";
+ first = false;
+ }
+ out << grammar.lookupOperandName(SPV_OPERAND_TYPE_CAPABILITY, uint32_t(c))
+ << "(" << uint32_t(c) << ")";
+ }
+ spvContextDestroy(ctx);
+ out << "}";
+ return out;
+}
+
// A test case for mapping an enum to a capability mask.
struct EnumCapabilityCase {
spv_operand_type_t type;
@@ -38,6 +62,16 @@ struct EnumCapabilityCase {
CapabilitySet expected_capabilities;
};
+// Emits an EnumCapabilityCase to the given output stream. This is used
+// to emit failure cases when they occur, which helps debug tests.
+inline std::ostream& operator<<(std::ostream& out, EnumCapabilityCase e) {
+ out << "{" << spvOperandTypeStr(e.type) << " " << e.value << " "
+ << e.expected_capabilities << " }";
+ return out;
+}
+
+using EnvEnumCapabilityCase = std::tuple<spv_target_env, EnumCapabilityCase>;
+
// Test fixture for testing EnumCapabilityCases.
using EnumCapabilityTest =
TestWithParam<std::tuple<spv_target_env, EnumCapabilityCase>>;
@@ -56,7 +90,7 @@ TEST_P(EnumCapabilityTest, Sample) {
EXPECT_THAT(ElementsIn(cap_set),
Eq(ElementsIn(std::get<1>(GetParam()).expected_capabilities)))
- << " capability value " << std::get<1>(GetParam()).value;
+ << " enum value " << std::get<1>(GetParam()).value;
spvContextDestroy(context);
}
@@ -237,25 +271,21 @@ INSTANTIATE_TEST_SUITE_P(
SamplerAddressingMode, EnumCapabilityTest,
Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
ValuesIn(std::vector<EnumCapabilityCase>{
- CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::None,
- Kernel),
- CASE1(SAMPLER_ADDRESSING_MODE,
- SamplerAddressingMode::ClampToEdge, Kernel),
- CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Clamp,
- Kernel),
- CASE1(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Repeat,
- Kernel),
- CASE1(SAMPLER_ADDRESSING_MODE,
- SamplerAddressingMode::RepeatMirrored, Kernel),
- })));
+ CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::None),
+ CASE0(SAMPLER_ADDRESSING_MODE,
+ SamplerAddressingMode::ClampToEdge),
+ CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Clamp),
+ CASE0(SAMPLER_ADDRESSING_MODE, SamplerAddressingMode::Repeat),
+ CASE0(SAMPLER_ADDRESSING_MODE,
+ SamplerAddressingMode::RepeatMirrored)})));
// See SPIR-V Section 3.10 Sampler Filter Mode
INSTANTIATE_TEST_SUITE_P(
SamplerFilterMode, EnumCapabilityTest,
Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
ValuesIn(std::vector<EnumCapabilityCase>{
- CASE1(SAMPLER_FILTER_MODE, SamplerFilterMode::Nearest, Kernel),
- CASE1(SAMPLER_FILTER_MODE, SamplerFilterMode::Linear, Kernel),
+ CASE0(SAMPLER_FILTER_MODE, SamplerFilterMode::Nearest),
+ CASE0(SAMPLER_FILTER_MODE, SamplerFilterMode::Linear),
})));
// See SPIR-V Section 3.11 Image Format
@@ -310,56 +340,56 @@ INSTANTIATE_TEST_SUITE_P(
// See SPIR-V Section 3.12 Image Channel Order
INSTANTIATE_TEST_SUITE_P(
ImageChannelOrder, EnumCapabilityTest,
- Combine(
- Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
- ValuesIn(std::vector<EnumCapabilityCase>{
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::R, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::A, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RG, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RA, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGB, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBA, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::BGRA, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ARGB, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Intensity, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Luminance, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Rx, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGx, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBx, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Depth, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::DepthStencil, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGB, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBx, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBA, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sBGRA, Kernel),
- CASE1(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ABGR, Kernel),
- })));
+ Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
+ ValuesIn(std::vector<EnumCapabilityCase>{
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::R),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::A),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RG),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RA),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGB),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBA),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::BGRA),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ARGB),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Intensity),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Luminance),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Rx),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGx),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::RGBx),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::Depth),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::DepthStencil),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGB),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBx),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sRGBA),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::sBGRA),
+ CASE0(IMAGE_CHANNEL_ORDER, ImageChannelOrder::ABGR),
+ })));
// See SPIR-V Section 3.13 Image Channel Data Type
INSTANTIATE_TEST_SUITE_P(
ImageChannelDataType, EnumCapabilityTest,
- Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
- ValuesIn(std::vector<EnumCapabilityCase>{
- // clang-format off
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt8, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt16, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt8, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt16, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort565, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort555, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt8, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt16, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt32, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt8, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt16, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt32, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::HalfFloat, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::Float, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt24, Kernel),
- CASE1(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010_2, Kernel),
- // clang-format on
- })));
+ Combine(
+ Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
+ ValuesIn(std::vector<EnumCapabilityCase>{
+ // clang-format off
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt8),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SnormInt16),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt8),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt16),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort565),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormShort555),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt8),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt16),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::SignedInt32),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt8),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt16),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnsignedInt32),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::HalfFloat),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::Float),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt24),
+ CASE0(IMAGE_CHANNEL_DATA_TYPE, ImageChannelDataType::UnormInt101010_2),
+ // clang-format on
+ })));
// See SPIR-V Section 3.14 Image Operands
INSTANTIATE_TEST_SUITE_P(
@@ -417,7 +447,7 @@ INSTANTIATE_TEST_SUITE_P(
// See SPIR-V Section 3.20 Decoration
INSTANTIATE_TEST_SUITE_P(
- Decoration, EnumCapabilityTest,
+ Decoration_1_1, EnumCapabilityTest,
Combine(Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1),
ValuesIn(std::vector<EnumCapabilityCase>{
CASE1(DECORATION, Decoration::RelaxedPrecision, Shader),
@@ -461,7 +491,8 @@ INSTANTIATE_TEST_SUITE_P(
CASE1(DECORATION, Decoration::XfbBuffer, TransformFeedback),
CASE1(DECORATION, Decoration::XfbStride, TransformFeedback),
CASE1(DECORATION, Decoration::FuncParamAttr, Kernel),
- CASE1(DECORATION, Decoration::FPFastMathMode, Kernel),
+ CASE2(DECORATION, Decoration::FPFastMathMode, Kernel,
+ FloatControls2),
CASE1(DECORATION, Decoration::LinkageAttributes, Linkage),
CASE1(DECORATION, Decoration::NoContraction, Shader),
CASE1(DECORATION, Decoration::InputAttachmentIndex,
@@ -469,6 +500,13 @@ INSTANTIATE_TEST_SUITE_P(
CASE1(DECORATION, Decoration::Alignment, Kernel),
})));
+// See SPIR-V Section 3.20 Decoration
+INSTANTIATE_TEST_SUITE_P(Decoration_1_6, EnumCapabilityTest,
+ Combine(Values(SPV_ENV_UNIVERSAL_1_6),
+ ValuesIn(std::vector<EnumCapabilityCase>{
+ CASE2(DECORATION, Decoration::Uniform,
+ Shader, UniformDecoration)})));
+
#if 0
// SpecId has different requirements in v1.0 and v1.1:
INSTANTIATE_TEST_SUITE_P(DecorationSpecIdV10, EnumCapabilityTest,
diff --git a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
index 3b2d3844e..92d266bba 100644
--- a/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/opt/CMakeLists.txt
@@ -66,6 +66,7 @@ add_spvtools_unittest(TARGET opt
instruction_list_test.cpp
instruction_test.cpp
interface_var_sroa_test.cpp
+ invocation_interlock_placement_test.cpp
interp_fixup_test.cpp
ir_builder.cpp
ir_context_test.cpp
@@ -77,6 +78,7 @@ add_spvtools_unittest(TARGET opt
local_single_block_elim.cpp
local_single_store_elim_test.cpp
local_ssa_elim_test.cpp
+ modify_maximal_reconvergence_test.cpp
module_test.cpp
module_utils.h
optimizer_test.cpp
@@ -103,6 +105,8 @@ add_spvtools_unittest(TARGET opt
strip_debug_info_test.cpp
strip_nonsemantic_info_test.cpp
struct_cfg_analysis_test.cpp
+ switch_descriptorset_test.cpp
+ trim_capabilities_pass_test.cpp
type_manager_test.cpp
types_test.cpp
unify_const_test.cpp
@@ -115,3 +119,12 @@ add_spvtools_unittest(TARGET opt
LIBS SPIRV-Tools-opt
PCH_FILE pch_test_opt
)
+if (NOT "${SPIRV_SKIP_TESTS}" AND TARGET gmock_main)
+ if (MSVC)
+ if (${MSVC_VERSION} LESS 1920)
+ # The VS 2017 debug build requires /bigobj on test_opt
+ # https://github.com/KhronosGroup/SPIRV-Tools/issues/5335
+ target_compile_options(test_opt PRIVATE /bigobj)
+ endif()
+ endif()
+endif()
diff --git a/third_party/SPIRV-Tools/test/opt/aggressive_dead_code_elim_test.cpp b/third_party/SPIRV-Tools/test/opt/aggressive_dead_code_elim_test.cpp
index 83aab3c46..845c6a588 100644
--- a/third_party/SPIRV-Tools/test/opt/aggressive_dead_code_elim_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/aggressive_dead_code_elim_test.cpp
@@ -6764,7 +6764,7 @@ TEST_F(AggressiveDCETest, ShaderDebugInfoKeepInFunctionElimStoreVar) {
%60 = OpExtInst %void %1 DebugTypeVector %59 %uint_4
%58 = OpExtInst %void %1 DebugTypeMember %10 %60 %55 %uint_12 %uint_5 %uint_0 %uint_128 %uint_3
%57 = OpExtInst %void %1 DebugTypeComposite %8 %uint_1 %55 %uint_10 %uint_1 %56 %8 %uint_128 %uint_3 %58
- %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2
+ %63 = OpExtInst %void %1 DebugTypeVector %59 %uint_2
%62 = OpExtInst %void %1 DebugTypeMember %12 %63 %55 %uint_7 %uint_5 %uint_0 %uint_64 %uint_3
%61 = OpExtInst %void %1 DebugTypeComposite %11 %uint_1 %55 %uint_5 %uint_1 %56 %11 %uint_64 %uint_3 %62
%64 = OpExtInst %void %1 DebugTypeComposite %13 %uint_0 %55 %uint_0 %uint_0 %56 %14 %51 %uint_3
@@ -7884,6 +7884,114 @@ TEST_F(AggressiveDCETest, RemoveWhenUsingPrintfExtension) {
SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
}
+TEST_F(AggressiveDCETest, FunctionReturnPointer) {
+ // Run DCE when a function returning a pointer to a reference is present
+
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability PhysicalStorageBufferAddresses
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel PhysicalStorageBuffer64 GLSL450
+ OpEntryPoint Vertex %2 "main" %3 %4
+ OpSource GLSL 450
+ OpSourceExtension "GL_EXT_buffer_reference"
+ OpSourceExtension "GL_EXT_scalar_block_layout"
+ OpName %4 "color"
+ OpMemberDecorate %5 0 Offset 0
+ OpDecorate %5 Block
+ OpMemberDecorate %7 0 Offset 0
+ OpDecorate %7 Block
+ OpDecorate %8 AliasedPointer
+ OpDecorate %4 Location 0
+ %9 = OpTypeVoid
+ %10 = OpTypeFunction %9
+ OpTypeForwardPointer %11 PhysicalStorageBuffer
+ %12 = OpTypeInt 32 0
+ %5 = OpTypeStruct %12
+ %11 = OpTypePointer PhysicalStorageBuffer %5
+;CHECK: [[pt:%\w+]] = OpTypePointer PhysicalStorageBuffer {{%\w+}}
+ %13 = OpTypeFunction %11
+;CHECK: [[pt_fn:%\w+]] = OpTypeFunction [[pt]]
+ %7 = OpTypeStruct %11
+ %14 = OpTypePointer PushConstant %7
+ %3 = OpVariable %14 PushConstant
+ %15 = OpTypeInt 32 1
+ %16 = OpConstant %15 0
+ %17 = OpTypePointer PushConstant %11
+ %18 = OpTypePointer Function %11
+ %19 = OpTypeFloat 32
+ %20 = OpTypeVector %19 4
+ %21 = OpTypePointer Output %20
+ %4 = OpVariable %21 Output
+ %22 = OpConstant %19 1
+ %23 = OpConstant %19 0
+ %24 = OpConstantComposite %20 %22 %23 %22 %22
+ %6 = OpFunction %11 None %13
+;CHECK: [[fn:%\w+]] = OpFunction [[pt]] None [[pt_fn]]
+ %27 = OpLabel
+ %28 = OpAccessChain %17 %3 %16
+ %29 = OpLoad %11 %28
+ OpReturnValue %29
+ OpFunctionEnd
+ %2 = OpFunction %9 None %10
+ %25 = OpLabel
+ %8 = OpVariable %18 Function
+ %26 = OpFunctionCall %11 %6
+;CHECK: {{%\w+}} = OpFunctionCall [[pt]] [[fn]]
+ OpStore %8 %26
+ OpStore %4 %24
+ OpReturn
+ OpFunctionEnd
+)";
+
+ // For physical storage buffer support
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SinglePassRunAndMatch<AggressiveDCEPass>(text, true);
+}
+
+TEST_F(AggressiveDCETest, KeepBeginEndInvocationInterlock) {
+ // OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT delimit a
+ // critical section. As such, they should be treated as if they have side
+ // effects and should not be removed.
+ const std::string test =
+ R"(OpCapability Shader
+OpCapability FragmentShaderSampleInterlockEXT
+OpExtension "SPV_EXT_fragment_shader_interlock"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %1 "main" %gl_FragCoord
+OpExecutionMode %1 OriginUpperLeft
+OpExecutionMode %1 SampleInterlockOrderedEXT
+OpDecorate %gl_FragCoord BuiltIn FragCoord
+%float = OpTypeFloat 32
+%float_0 = OpConstant %float 0
+%v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%void = OpTypeVoid
+%8 = OpTypeFunction %void
+%bool = OpTypeBool
+%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+%1 = OpFunction %void None %8
+%10 = OpLabel
+%11 = OpLoad %v4float %gl_FragCoord
+%12 = OpCompositeExtract %float %11 0
+%13 = OpFOrdGreaterThan %bool %12 %float_0
+OpSelectionMerge %14 None
+OpBranchConditional %13 %15 %16
+%15 = OpLabel
+OpBeginInvocationInterlockEXT
+OpBranch %14
+%16 = OpLabel
+OpBeginInvocationInterlockEXT
+OpBranch %14
+%14 = OpLabel
+OpEndInvocationInterlockEXT
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<AggressiveDCEPass>(test, test, true, true);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/amd_ext_to_khr.cpp b/third_party/SPIRV-Tools/test/opt/amd_ext_to_khr.cpp
index 3340e898c..a520d600b 100644
--- a/third_party/SPIRV-Tools/test/opt/amd_ext_to_khr.cpp
+++ b/third_party/SPIRV-Tools/test/opt/amd_ext_to_khr.cpp
@@ -26,15 +26,17 @@ using AmdExtToKhrTest = PassTest<::testing::Test>;
using ::testing::HasSubstr;
-std::string GetTest(std::string op_code, std::string new_op_code) {
+std::string GetTest(std::string op_code, std::string new_op_code,
+ bool is_float = false) {
const std::string text = R"(
; CHECK: OpCapability Shader
; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
; CHECK: OpFunction
; CHECK-NEXT: OpLabel
-; CHECK-NEXT: [[undef:%\w+]] = OpUndef %uint
+; CHECK-NEXT: [[undef:%\w+]] = OpUndef %
; CHECK-NEXT: )" + new_op_code +
- R"( %uint %uint_3 Reduce [[undef]]
+ " %" + (is_float ? "float" : "uint") +
+ R"( %uint_3 Reduce [[undef]]
OpCapability Shader
OpCapability Groups
OpExtension "SPV_AMD_shader_ballot"
@@ -44,12 +46,15 @@ std::string GetTest(std::string op_code, std::string new_op_code) {
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
%uint_3 = OpConstant %uint 3
%1 = OpFunction %void None %3
%6 = OpLabel
- %7 = OpUndef %uint
+ %7 = OpUndef %)" +
+ (is_float ? "float" : "uint") + R"(
%8 = )" + op_code +
- R"( %uint %uint_3 Reduce %7
+ " %" + (is_float ? "float" : "uint") +
+ R"( %uint_3 Reduce %7
OpReturn
OpFunctionEnd
@@ -64,7 +69,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupIAddNonUniformAMD) {
}
TEST_F(AmdExtToKhrTest, ReplaceGroupFAddNonUniformAMD) {
std::string text =
- GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd");
+ GetTest("OpGroupFAddNonUniformAMD", "OpGroupNonUniformFAdd", true);
SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
}
TEST_F(AmdExtToKhrTest, ReplaceGroupUMinNonUniformAMD) {
@@ -79,7 +84,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupSMinNonUniformAMD) {
}
TEST_F(AmdExtToKhrTest, ReplaceGroupFMinNonUniformAMD) {
std::string text =
- GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin");
+ GetTest("OpGroupFMinNonUniformAMD", "OpGroupNonUniformFMin", true);
SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
}
TEST_F(AmdExtToKhrTest, ReplaceGroupUMaxNonUniformAMD) {
@@ -94,7 +99,7 @@ TEST_F(AmdExtToKhrTest, ReplaceGroupSMaxNonUniformAMD) {
}
TEST_F(AmdExtToKhrTest, ReplaceGroupFMaxNonUniformAMD) {
std::string text =
- GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax");
+ GetTest("OpGroupFMaxNonUniformAMD", "OpGroupNonUniformFMax", true);
SinglePassRunAndMatch<AmdExtensionToKhrPass>(text, true);
}
diff --git a/third_party/SPIRV-Tools/test/opt/block_merge_test.cpp b/third_party/SPIRV-Tools/test/opt/block_merge_test.cpp
index 57c5061fd..331ce3a7a 100644
--- a/third_party/SPIRV-Tools/test/opt/block_merge_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/block_merge_test.cpp
@@ -1320,6 +1320,148 @@ OpFunctionEnd
SinglePassRunAndMatch<BlockMergePass>(text, true);
}
+TEST_F(BlockMergeTest, MaximalReconvergenceNoMeldToMerge) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability GroupNonUniformBallot
+ OpCapability GroupNonUniformArithmetic
+ OpExtension "SPV_KHR_maximal_reconvergence"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID %output
+ OpExecutionMode %main LocalSize 1 1 1
+ OpExecutionMode %main MaximallyReconvergesKHR
+ OpSource HLSL 660
+ OpName %type_RWStructuredBuffer_uint "type.RWStructuredBuffer.uint"
+ OpName %output "output"
+ OpName %main "main"
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpDecorate %output DescriptorSet 0
+ OpDecorate %output Binding 0
+ OpDecorate %_runtimearr_uint ArrayStride 4
+ OpMemberDecorate %type_RWStructuredBuffer_uint 0 Offset 0
+ OpDecorate %type_RWStructuredBuffer_uint Block
+ %uint = OpTypeInt 32 0
+ %bool = OpTypeBool
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %int_1 = OpConstant %int 1
+ %_runtimearr_uint = OpTypeRuntimeArray %uint
+ %type_RWStructuredBuffer_uint = OpTypeStruct %_runtimearr_uint
+ %_ptr_StorageBuffer_type_RWStructuredBuffer_uint = OpTypePointer StorageBuffer %type_RWStructuredBuffer_uint
+ %v3uint = OpTypeVector %uint 3
+ %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+ %void = OpTypeVoid
+ %15 = OpTypeFunction %void
+ %uint_3 = OpConstant %uint 3
+ %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+ %output = OpVariable %_ptr_StorageBuffer_type_RWStructuredBuffer_uint StorageBuffer
+ %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %main = OpFunction %void None %15
+ %18 = OpLabel
+ %19 = OpLoad %v3uint %gl_GlobalInvocationID
+ OpBranch %20
+ %20 = OpLabel
+ OpLoopMerge %21 %22 None
+; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]]
+ OpBranch %23
+ %23 = OpLabel
+ %24 = OpCompositeExtract %uint %19 0
+ %25 = OpGroupNonUniformBroadcastFirst %uint %uint_3 %24
+ %26 = OpIEqual %bool %24 %25
+ OpSelectionMerge %27 None
+ OpBranchConditional %26 %28 %27
+ %28 = OpLabel
+ %29 = OpGroupNonUniformIAdd %int %uint_3 Reduce %int_1
+ %30 = OpBitcast %uint %29
+ OpBranch %21
+; CHECK: [[t1:%\w+]] = OpGroupNonUniformIAdd %int %uint_3 Reduce %int_1
+; CHECK-NEXT: [[t2:%\w+]] = OpBitcast %uint [[t1]]
+; CHECK-NEXT: OpBranch [[merge]]
+ %27 = OpLabel
+ OpBranch %22
+ %22 = OpLabel
+ OpBranch %20
+ %21 = OpLabel
+ %31 = OpAccessChain %_ptr_StorageBuffer_uint %output %int_0 %24
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ SinglePassRunAndMatch<BlockMergePass>(text, true);
+}
+
+TEST_F(BlockMergeTest, NoMaximalReconvergenceMeldToMerge) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability GroupNonUniformBallot
+ OpCapability GroupNonUniformArithmetic
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID %output
+ OpExecutionMode %main LocalSize 1 1 1
+ OpSource HLSL 660
+ OpName %type_RWStructuredBuffer_uint "type.RWStructuredBuffer.uint"
+ OpName %output "output"
+ OpName %main "main"
+ OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+ OpDecorate %output DescriptorSet 0
+ OpDecorate %output Binding 0
+ OpDecorate %_runtimearr_uint ArrayStride 4
+ OpMemberDecorate %type_RWStructuredBuffer_uint 0 Offset 0
+ OpDecorate %type_RWStructuredBuffer_uint Block
+ %uint = OpTypeInt 32 0
+ %bool = OpTypeBool
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ %int_1 = OpConstant %int 1
+ %_runtimearr_uint = OpTypeRuntimeArray %uint
+ %type_RWStructuredBuffer_uint = OpTypeStruct %_runtimearr_uint
+ %_ptr_StorageBuffer_type_RWStructuredBuffer_uint = OpTypePointer StorageBuffer %type_RWStructuredBuffer_uint
+ %v3uint = OpTypeVector %uint 3
+ %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+ %void = OpTypeVoid
+ %15 = OpTypeFunction %void
+ %uint_3 = OpConstant %uint 3
+ %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+ %output = OpVariable %_ptr_StorageBuffer_type_RWStructuredBuffer_uint StorageBuffer
+ %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %main = OpFunction %void None %15
+ %18 = OpLabel
+ %19 = OpLoad %v3uint %gl_GlobalInvocationID
+ OpBranch %20
+ %20 = OpLabel
+ OpLoopMerge %21 %22 None
+; CHECK: OpLoopMerge [[merge:%\w+]] [[continue:%\w+]]
+ OpBranch %23
+ %23 = OpLabel
+ %24 = OpCompositeExtract %uint %19 0
+ %25 = OpGroupNonUniformBroadcastFirst %uint %uint_3 %24
+ %26 = OpIEqual %bool %24 %25
+ OpSelectionMerge %27 None
+ OpBranchConditional %26 %28 %27
+ %28 = OpLabel
+ %29 = OpGroupNonUniformIAdd %int %uint_3 Reduce %int_1
+ %30 = OpBitcast %uint %29
+ OpBranch %21
+; CHECK: [[merge]] = OpLabel
+; CHECK-NEXT: [[t1:%\w+]] = OpGroupNonUniformIAdd %int %uint_3 Reduce %int_1
+; CHECK-NEXT: [[t2:%\w+]] = OpBitcast %uint [[t1]]
+ %27 = OpLabel
+ OpBranch %22
+ %22 = OpLabel
+ OpBranch %20
+ %21 = OpLabel
+ %31 = OpAccessChain %_ptr_StorageBuffer_uint %output %int_0 %24
+ OpStore %31 %30
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ SinglePassRunAndMatch<BlockMergePass>(text, true);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// More complex control flow
diff --git a/third_party/SPIRV-Tools/test/opt/convert_relaxed_to_half_test.cpp b/third_party/SPIRV-Tools/test/opt/convert_relaxed_to_half_test.cpp
index 27330e109..c5774045c 100644
--- a/third_party/SPIRV-Tools/test/opt/convert_relaxed_to_half_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/convert_relaxed_to_half_test.cpp
@@ -1613,6 +1613,175 @@ OpFunctionEnd
SinglePassRunAndCheck<ConvertToHalfPass>(test, test, true);
}
+TEST_F(ConvertToHalfTest, PreserveImageOperandPrecision) {
+ // Ensure that a non-relaxed texture coordinate does not get relaxed nor
+ // converted to half precision if the image instruction is marked relaxed.
+
+ // Also ensure that a relaxed local variable does get converted to half
+ // precision before being passed to an image opeartor.
+
+ // #version 310 es
+ //
+ // precision mediump float;
+ //
+ // layout(location = 10) in highp vec4 vertex_uv01;
+ // layout(binding = 0, set = 3) uniform sampler2D materialParams_baseColorMap;
+ //
+ // layout(location = 0) out vec4 fragColor;
+ //
+ // void main() {
+ // vec4 uv = vec4(2.0);
+ // fragColor = texture(materialParams_baseColorMap, uv.xy);
+ // fragColor = texture(materialParams_baseColorMap, vertex_uv01.xy);
+ // }
+ const std::string test = R"(
+ OpCapability Shader
+ OpCapability Float16
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %4 "main" %13 %25
+ OpExecutionMode %4 OriginUpperLeft
+ OpSource ESSL 310
+ OpDecorate %9 RelaxedPrecision
+;CHECK: OpDecorate [[uv:%\w+]] RelaxedPrecision
+ OpDecorate %13 Location 0
+ OpDecorate %17 DescriptorSet 3
+ OpDecorate %17 Binding 0
+ OpDecorate %18 RelaxedPrecision
+ OpDecorate %23 RelaxedPrecision
+ OpDecorate %25 Location 10
+ %2 = OpTypeVoid
+ %3 = OpTypeFunction %2
+ %6 = OpTypeFloat 32
+;CHECK: [[float32_t:%\w+]] = OpTypeFloat 32
+ %7 = OpTypeVector %6 4
+;CHECK: [[vec4_t:%\w+]] = OpTypeVector [[float32_t]] 4
+ %8 = OpTypePointer Function %7
+ %10 = OpConstant %6 2
+ %11 = OpConstantComposite %7 %10 %10 %10 %10
+ %12 = OpTypePointer Output %7
+;CHECK: [[output_ptr_t:%\w+]] = OpTypePointer Output [[vec4_t]]
+ %13 = OpVariable %12 Output
+;CHECK: [[output:%\w+]] = OpVariable [[output_ptr_t]] Output
+ %14 = OpTypeImage %6 2D 0 0 0 1 Unknown
+ %15 = OpTypeSampledImage %14
+ %16 = OpTypePointer UniformConstant %15
+ %17 = OpVariable %16 UniformConstant
+ %19 = OpTypeVector %6 2
+;CHECK: [[vec2_t:%\w+]] = OpTypeVector [[float32_t]] 2
+ %24 = OpTypePointer Input %7
+;CHECK: [[input_ptr_t:%\w+]] = OpTypePointer Input [[vec4_t]]
+ %25 = OpVariable %24 Input
+ %29 = OpTypeFloat 16
+;CHECK: [[float16_t:%\w+]] = OpTypeFloat 16
+ %30 = OpTypeVector %29 4
+ %33 = OpTypeVector %29 2
+;CHECK: [[vec2_16b_t:%\w+]] = OpTypeVector [[float16_t]] 2
+ %4 = OpFunction %2 None %3
+ %5 = OpLabel
+
+; The only Function storage variable is marked as relaxed
+ %9 = OpVariable %8 Function
+;CHECK: [[uv]] = OpVariable {{%\w+}} Function
+ OpStore %9 %11
+ %18 = OpLoad %15 %17
+ %20 = OpLoad %7 %9
+ %31 = OpFConvert %30 %20
+ %32 = OpFConvert %30 %20
+
+; The first sample op should get a 16b coordinate
+ %21 = OpVectorShuffle %33 %31 %32 0 1
+;CHECK: [[uv_16b:%\w+]] = OpVectorShuffle [[vec2_16b_t]]
+ %22 = OpImageSampleImplicitLod %7 %18 %21
+;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_16b]]
+
+ OpStore %13 %22
+ %23 = OpLoad %15 %17
+ %26 = OpLoad %7 %25
+
+; The second sample op should get a 32b coordinate
+ %27 = OpVectorShuffle %19 %26 %26 0 1
+;CHECK: [[uv_32b:%\w+]] = OpVectorShuffle [[vec2_t]]
+ %28 = OpImageSampleImplicitLod %7 %23 %27
+;CHECK: OpImageSampleImplicitLod [[vec4_t]] {{%\w+}} [[uv_32b]]
+
+ OpStore %13 %28
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ SinglePassRunAndMatch<ConvertToHalfPass>(test, true);
+}
+
+TEST_F(ConvertToHalfTest, DontRelaxDecoratedOpCompositeExtract) {
+ // This test checks that a OpCompositeExtract with a Struct operand won't be
+ // relaxed, even if it is explicitly decorated with RelaxedPrecision.
+ const std::string test =
+ R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %1 "main"
+OpExecutionMode %1 OriginUpperLeft
+OpDecorate %9 RelaxedPrecision
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_struct_6 = OpTypeStruct %v4float
+%7 = OpUndef %_struct_6
+%1 = OpFunction %void None %3
+%8 = OpLabel
+%9 = OpCompositeExtract %float %7 0 3
+OpReturn
+OpFunctionEnd
+)";
+
+ const std::string expected =
+ R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %1 "main"
+OpExecutionMode %1 OriginUpperLeft
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_struct_6 = OpTypeStruct %v4float
+%7 = OpUndef %_struct_6
+%1 = OpFunction %void None %3
+%8 = OpLabel
+%9 = OpCompositeExtract %float %7 0 3
+OpReturn
+OpFunctionEnd
+)";
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndCheck<ConvertToHalfPass>(test, expected, true);
+}
+
+TEST_F(ConvertToHalfTest, DontRelaxOpCompositeExtract) {
+ // This test checks that a OpCompositeExtract with a Struct operand won't be
+ // relaxed, even if its result has no uses.
+ const std::string test =
+ R"(OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %1 "main"
+OpExecutionMode %1 OriginUpperLeft
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_struct_6 = OpTypeStruct %v4float
+%7 = OpUndef %_struct_6
+%1 = OpFunction %void None %3
+%8 = OpLabel
+%9 = OpCompositeExtract %float %7 0 3
+OpReturn
+OpFunctionEnd
+)";
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndCheck<ConvertToHalfPass>(test, test, true);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/copy_prop_array_test.cpp b/third_party/SPIRV-Tools/test/opt/copy_prop_array_test.cpp
index 2d4b7a3b6..16719b870 100644
--- a/third_party/SPIRV-Tools/test/opt/copy_prop_array_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/copy_prop_array_test.cpp
@@ -1942,6 +1942,41 @@ OpFunctionEnd
SinglePassRunAndCheck<CopyPropagateArrays>(text, text, false);
}
+
+// If the size of an array used in an OpCompositeInsert is not known at compile
+// time, then we should not propagate the array, because we do not have a single
+// array that represents the final value.
+TEST_F(CopyPropArrayPassTest, SpecConstSizedArray) {
+ const std::string text = R"(OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %2 "main"
+OpExecutionMode %2 OriginUpperLeft
+%void = OpTypeVoid
+%4 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%uint = OpTypeInt 32 0
+%7 = OpSpecConstant %uint 32
+%_arr_int_7 = OpTypeArray %int %7
+%int_63 = OpConstant %int 63
+%uint_0 = OpConstant %uint 0
+%bool = OpTypeBool
+%int_0 = OpConstant %int 0
+%int_587202566 = OpConstant %int 587202566
+%false = OpConstantFalse %bool
+%_ptr_Function__arr_int_7 = OpTypePointer Function %_arr_int_7
+%16 = OpUndef %_arr_int_7
+%2 = OpFunction %void None %4
+%17 = OpLabel
+%18 = OpVariable %_ptr_Function__arr_int_7 Function
+%19 = OpCompositeInsert %_arr_int_7 %int_0 %16 0
+OpStore %18 %19
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndCheck<CopyPropagateArrays>(text, text, false);
+}
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/dead_insert_elim_test.cpp b/third_party/SPIRV-Tools/test/opt/dead_insert_elim_test.cpp
index 268e65906..fcc3dde48 100644
--- a/third_party/SPIRV-Tools/test/opt/dead_insert_elim_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/dead_insert_elim_test.cpp
@@ -736,6 +736,113 @@ OpFunctionEnd
SinglePassRunAndMatch<DeadInsertElimPass>(text, true);
}
+TEST_F(DeadInsertElimTest, PhiOverEmptyStruct) {
+ // Reproducer for nullptr access error in MarkInsertChain
+ // that occurs when processing a phi operation with an
+ // empty struct result type.
+ //
+ // Note: Disassembly created from HLSL source with
+ // dxc -T cs_6_6 -spirv -Oconfig=
+ // --eliminate-dead-branches,--merge-return,--ssa-rewrite
+ //
+ // RWBuffer<float> buf;
+ //
+ // struct S { };
+ //
+ // S fn() {
+ // S s = (S)0;
+ // if (buf[0] > 0) {
+ // return s;
+ // }
+ // return s;
+ // }
+ //
+ // [numthreads(1,1,1)]
+ // void main() {
+ // fn();
+ // }
+
+ const std::string disassembly =
+ R"(OpCapability Shader
+ OpCapability SampledBuffer
+ OpCapability ImageBuffer
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpSource HLSL 660
+ OpName %S "S"
+ OpName %type_buffer_image "type.buffer.image"
+ OpName %buf "buf"
+ OpName %main "main"
+ OpName %src_main "src.main"
+ OpName %bb_entry "bb.entry"
+ OpName %fn "fn"
+ OpName %bb_entry_0 "bb.entry"
+ OpName %s "s"
+ OpName %if_true "if.true"
+ OpName %if_merge "if.merge"
+ OpDecorate %buf DescriptorSet 0
+ OpDecorate %buf Binding 0
+ %S = OpTypeStruct
+ %4 = OpConstantNull %S
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %float = OpTypeFloat 32
+ %float_0 = OpConstant %float 0
+%type_buffer_image = OpTypeImage %float Buffer 2 0 0 2 R32f
+%_ptr_UniformConstant_type_buffer_image = OpTypePointer UniformConstant %type_buffer_image
+ %void = OpTypeVoid
+ %12 = OpTypeFunction %void
+ %19 = OpTypeFunction %S
+%_ptr_Function_S = OpTypePointer Function %S
+ %v4float = OpTypeVector %float 4
+ %bool = OpTypeBool
+ %buf = OpVariable %_ptr_UniformConstant_type_buffer_image UniformConstant
+ %false = OpConstantFalse %bool
+%_ptr_Function_bool = OpTypePointer Function %bool
+ %true = OpConstantTrue %bool
+ %main = OpFunction %void None %12
+ %13 = OpLabel
+ %14 = OpFunctionCall %void %src_main
+ OpReturn
+ OpFunctionEnd
+ %src_main = OpFunction %void None %12
+ %bb_entry = OpLabel
+ %17 = OpFunctionCall %S %fn
+ OpReturn
+ OpFunctionEnd
+ %fn = OpFunction %S None %19
+ %bb_entry_0 = OpLabel
+ %39 = OpVariable %_ptr_Function_bool Function %false
+ %34 = OpVariable %_ptr_Function_S Function
+ %s = OpVariable %_ptr_Function_S Function
+ OpSelectionMerge %33 None
+ OpSwitch %uint_0 %36
+ %36 = OpLabel
+ OpStore %s %4
+ %23 = OpLoad %type_buffer_image %buf
+ %25 = OpImageRead %v4float %23 %uint_0 None
+ %26 = OpCompositeExtract %float %25 0
+ %28 = OpFOrdGreaterThan %bool %26 %float_0
+ OpSelectionMerge %if_merge None
+ OpBranchConditional %28 %if_true %if_merge
+ %if_true = OpLabel
+ OpStore %39 %true
+ OpStore %34 %4
+ OpBranch %33
+ %if_merge = OpLabel
+ OpStore %39 %true
+ OpStore %34 %4
+ OpBranch %33
+ %33 = OpLabel
+ %41 = OpPhi %S %4 %if_true %4 %if_merge
+ OpReturnValue %41
+ OpFunctionEnd
+)";
+ // Used to crash with a nullptr access violation when processing %41
+ SinglePassRunToBinary<DeadInsertElimPass>(disassembly, true);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
diff --git a/third_party/SPIRV-Tools/test/opt/desc_sroa_test.cpp b/third_party/SPIRV-Tools/test/opt/desc_sroa_test.cpp
index 7a118f988..5c166d83f 100644
--- a/third_party/SPIRV-Tools/test/opt/desc_sroa_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/desc_sroa_test.cpp
@@ -918,6 +918,74 @@ TEST_F(DescriptorScalarReplacementTest, DecorateStringForReflect) {
SinglePassRunAndMatch<DescriptorScalarReplacement>(shader, true);
}
+TEST_F(DescriptorScalarReplacementTest, ExpandArrayInOpEntryPoint) {
+ const std::string text = R"(; SPIR-V
+; Version: 1.6
+; Bound: 31
+; Schema: 0
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+
+; CHECK: OpEntryPoint GLCompute %main "main" %output_0_ %output_1_
+
+ OpEntryPoint GLCompute %main "main" %output
+ OpExecutionMode %main LocalSize 1 1 1
+ OpSource HLSL 670
+ OpName %type_RWByteAddressBuffer "type.RWByteAddressBuffer"
+ OpName %output "output"
+ OpName %main "main"
+ OpName %src_main "src.main"
+ OpName %bb_entry "bb.entry"
+
+; CHECK: OpDecorate %output_1_ DescriptorSet 0
+; CHECK: OpDecorate %output_1_ Binding 1
+; CHECK: OpDecorate %output_0_ DescriptorSet 0
+; CHECK: OpDecorate %output_0_ Binding 0
+
+ OpDecorate %output DescriptorSet 0
+ OpDecorate %output Binding 0
+
+ OpDecorate %_runtimearr_uint ArrayStride 4
+ OpMemberDecorate %type_RWByteAddressBuffer 0 Offset 0
+ OpDecorate %type_RWByteAddressBuffer Block
+ %int = OpTypeInt 32 1
+ %int_1 = OpConstant %int 1
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_2 = OpConstant %uint 2
+ %uint_32 = OpConstant %uint 32
+%_runtimearr_uint = OpTypeRuntimeArray %uint
+%type_RWByteAddressBuffer = OpTypeStruct %_runtimearr_uint
+%_arr_type_RWByteAddressBuffer_uint_2 = OpTypeArray %type_RWByteAddressBuffer %uint_2
+%_ptr_StorageBuffer__arr_type_RWByteAddressBuffer_uint_2 = OpTypePointer StorageBuffer %_arr_type_RWByteAddressBuffer_uint_2
+ %void = OpTypeVoid
+ %23 = OpTypeFunction %void
+%_ptr_StorageBuffer_type_RWByteAddressBuffer = OpTypePointer StorageBuffer %type_RWByteAddressBuffer
+%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
+
+; CHECK: %output_1_ = OpVariable %_ptr_StorageBuffer_type_RWByteAddressBuffer StorageBuffer
+; CHECK: %output_0_ = OpVariable %_ptr_StorageBuffer_type_RWByteAddressBuffer StorageBuffer
+
+ %output = OpVariable %_ptr_StorageBuffer__arr_type_RWByteAddressBuffer_uint_2 StorageBuffer
+
+ %main = OpFunction %void None %23
+ %26 = OpLabel
+ %27 = OpFunctionCall %void %src_main
+ OpReturn
+ OpFunctionEnd
+ %src_main = OpFunction %void None %23
+ %bb_entry = OpLabel
+ %28 = OpAccessChain %_ptr_StorageBuffer_type_RWByteAddressBuffer %output %int_1
+ %29 = OpShiftRightLogical %uint %uint_0 %uint_2
+ %30 = OpAccessChain %_ptr_StorageBuffer_uint %28 %uint_0 %29
+ OpStore %30 %uint_32
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ SinglePassRunAndMatch<DescriptorScalarReplacement>(text, false);
+}
+
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/feature_manager_test.cpp b/third_party/SPIRV-Tools/test/opt/feature_manager_test.cpp
index a5105a9ac..7e8f92c3c 100644
--- a/third_party/SPIRV-Tools/test/opt/feature_manager_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/feature_manager_test.cpp
@@ -87,6 +87,25 @@ OpExtension "SPV_KHR_storage_buffer_storage_class"
Extension::kSPV_KHR_storage_buffer_storage_class));
}
+TEST_F(FeatureManagerTest, GetExtensionsReturnsExtensions) {
+ const std::string text = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpExtension "SPV_KHR_variable_pointers"
+OpExtension "SPV_KHR_storage_buffer_storage_class"
+ )";
+
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ASSERT_NE(context, nullptr);
+
+ const auto& extensions = context->get_feature_mgr()->GetExtensions();
+ EXPECT_EQ(extensions.size(), 2);
+ EXPECT_TRUE(extensions.contains(Extension::kSPV_KHR_variable_pointers));
+ EXPECT_TRUE(
+ extensions.contains(Extension::kSPV_KHR_storage_buffer_storage_class));
+}
+
// Test capability checks.
TEST_F(FeatureManagerTest, ExplicitlyPresent1) {
const std::string text = R"(
@@ -142,6 +161,24 @@ OpMemoryModel Logical GLSL450
context->get_feature_mgr()->HasCapability(spv::Capability::Kernel));
}
+TEST_F(FeatureManagerTest, GetCapabilitiesReturnsImplicitCapabilities) {
+ const std::string text = R"(
+OpCapability Tessellation
+OpMemoryModel Logical GLSL450
+ )";
+
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_2, nullptr, text);
+ ASSERT_NE(context, nullptr);
+
+ const auto& capabilities = context->get_feature_mgr()->GetCapabilities();
+ // Tesselation implies Shader, which implies Matrix.
+ EXPECT_EQ(capabilities.size(), 3);
+ EXPECT_TRUE(capabilities.contains(spv::Capability::Tessellation));
+ EXPECT_TRUE(capabilities.contains(spv::Capability::Shader));
+ EXPECT_TRUE(capabilities.contains(spv::Capability::Matrix));
+}
+
} // namespace
} // namespace opt
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/fix_storage_class_test.cpp b/third_party/SPIRV-Tools/test/opt/fix_storage_class_test.cpp
index 93ce87360..684e006ec 100644
--- a/third_party/SPIRV-Tools/test/opt/fix_storage_class_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fix_storage_class_test.cpp
@@ -874,6 +874,47 @@ TEST_F(FixTypeTest, FixPhiInLoop) {
SinglePassRunAndMatch<FixStorageClass>(text, false);
}
+TEST_F(FixStorageClassTest, SupportsU64Index) {
+ const std::string text = R"(
+; CHECK: OpAccessChain %_ptr_Uniform_float
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "testMain" %gl_LocalInvocationID
+ OpExecutionMode %1 LocalSize 8 8 1
+ OpDecorate %gl_LocalInvocationID BuiltIn LocalInvocationId
+ OpDecorate %8 DescriptorSet 0
+ OpDecorate %8 Binding 0
+ OpDecorate %_runtimearr_float ArrayStride 4
+ OpMemberDecorate %_struct_7 0 Offset 0
+ OpDecorate %_struct_7 BufferBlock
+ %ulong = OpTypeInt 64 0
+ %ulong_0 = OpConstant %ulong 0
+ %float = OpTypeFloat 32
+ %float_123 = OpConstant %float 123
+ %uint = OpTypeInt 32 0
+ %uint_10 = OpConstant %uint 10
+%_runtimearr_float = OpTypeRuntimeArray %float
+ %_struct_7 = OpTypeStruct %_runtimearr_float
+%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
+ %v3uint = OpTypeVector %uint 3
+%_ptr_Input_v3uint = OpTypePointer Input %v3uint
+ %void = OpTypeVoid
+ %30 = OpTypeFunction %void
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+ %8 = OpVariable %_ptr_Uniform__struct_7 Uniform
+%gl_LocalInvocationID = OpVariable %_ptr_Input_v3uint Input
+ %1 = OpFunction %void None %30
+ %38 = OpLabel
+ %44 = OpLoad %v3uint %gl_LocalInvocationID
+ %59 = OpCompositeExtract %uint %44 0
+ %60 = OpAccessChain %_ptr_Uniform_float %8 %ulong_0 %59
+ OpStore %60 %float_123
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<FixStorageClass>(text, false);
+}
} // namespace
} // namespace opt
diff --git a/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp b/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
index f83e86e96..335e0f516 100644
--- a/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fold_spec_const_op_composite_test.cpp
@@ -674,6 +674,31 @@ TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, CompositeInsertMatrixNull) {
SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
}
+// Silently ignore spec constants that cannot be folded
+TEST_F(FoldSpecConstantOpAndCompositePassBasicTest, UnfoldableOp) {
+ const std::string test = R"(
+ OpCapability Shader
+ OpCapability SignedZeroInfNanPreserve
+ OpExtension "SPV_KHR_float_controls"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main"
+ OpSource GLSL 450
+ OpDecorate %v SpecId 1
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v = OpConstant %float 0x1p-1
+%c = OpSpecConstantOp %float QuantizeToF16 %v
+;CHECK: {{%\w+}} = OpSpecConstantOp {{%\w+}} QuantizeToF16 {{%\w+}}
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<FoldSpecConstantOpAndCompositePass>(test, false);
+}
+
// All types and some common constants that are potentially required in
// FoldSpecConstantOpAndCompositeTest.
std::vector<std::string> CommonTypesAndConstants() {
@@ -1033,14 +1058,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%true = OpConstantTrue %bool",
- "%true_0 = OpConstantTrue %bool",
"%spec_bool_t_vec = OpConstantComposite %v2bool %bool_true %bool_true",
- "%false = OpConstantFalse %bool",
- "%false_0 = OpConstantFalse %bool",
"%spec_bool_f_vec = OpConstantComposite %v2bool %bool_false %bool_false",
- "%false_1 = OpConstantFalse %bool",
- "%false_2 = OpConstantFalse %bool",
"%spec_bool_from_null = OpConstantComposite %v2bool %bool_false %bool_false",
},
},
@@ -1055,14 +1074,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%true = OpConstantTrue %bool",
- "%true_0 = OpConstantTrue %bool",
"%spec_bool_t_vec = OpConstantComposite %v2bool %bool_true %bool_true",
- "%false = OpConstantFalse %bool",
- "%false_0 = OpConstantFalse %bool",
"%spec_bool_f_vec = OpConstantComposite %v2bool %bool_false %bool_false",
- "%false_1 = OpConstantFalse %bool",
- "%false_2 = OpConstantFalse %bool",
"%spec_bool_from_null = OpConstantComposite %v2bool %bool_false %bool_false",
},
},
@@ -1077,14 +1090,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%int_1 = OpConstant %int 1",
- "%int_1_0 = OpConstant %int 1",
"%spec_int_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
- "%int_0 = OpConstant %int 0",
- "%int_0_0 = OpConstant %int 0",
"%spec_int_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
- "%int_0_1 = OpConstant %int 0",
- "%int_0_2 = OpConstant %int 0",
"%spec_int_from_null = OpConstantComposite %v2int %signed_zero %signed_zero",
},
},
@@ -1099,14 +1106,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%int_1 = OpConstant %int 1",
- "%int_1_0 = OpConstant %int 1",
"%spec_int_one_vec = OpConstantComposite %v2int %signed_one %signed_one",
- "%int_0 = OpConstant %int 0",
- "%int_0_0 = OpConstant %int 0",
"%spec_int_zero_vec = OpConstantComposite %v2int %signed_zero %signed_zero",
- "%int_0_1 = OpConstant %int 0",
- "%int_0_2 = OpConstant %int 0",
"%spec_int_from_null = OpConstantComposite %v2int %signed_zero %signed_zero",
},
},
@@ -1121,14 +1122,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%uint_1 = OpConstant %uint 1",
- "%uint_1_0 = OpConstant %uint 1",
"%spec_uint_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
- "%uint_0 = OpConstant %uint 0",
- "%uint_0_0 = OpConstant %uint 0",
"%spec_uint_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
- "%uint_0_1 = OpConstant %uint 0",
- "%uint_0_2 = OpConstant %uint 0",
"%spec_uint_from_null = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
},
},
@@ -1143,14 +1138,8 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%uint_1 = OpConstant %uint 1",
- "%uint_1_0 = OpConstant %uint 1",
"%spec_uint_one_vec = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
- "%uint_0 = OpConstant %uint 0",
- "%uint_0_0 = OpConstant %uint 0",
"%spec_uint_zero_vec = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
- "%uint_0_1 = OpConstant %uint 0",
- "%uint_0_2 = OpConstant %uint 0",
"%spec_uint_from_null = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
},
},
@@ -1159,8 +1148,6 @@ INSTANTIATE_TEST_SUITE_P(
{
// original
{
- "%spec_uint_zero = OpSpecConstantOp %uint UConvert %bool_false",
- "%spec_uint_one = OpSpecConstantOp %uint UConvert %bool_true",
"%spec_ulong_zero = OpSpecConstantOp %ulong UConvert %unsigned_zero",
"%spec_ulong_one = OpSpecConstantOp %ulong UConvert %unsigned_one",
"%spec_short_zero = OpSpecConstantOp %ushort UConvert %unsigned_zero",
@@ -1172,8 +1159,6 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%spec_uint_zero = OpConstant %uint 0",
- "%spec_uint_one = OpConstant %uint 1",
"%spec_ulong_zero = OpConstant %ulong 0",
"%spec_ulong_one = OpConstant %ulong 1",
"%spec_short_zero = OpConstant %ushort 0",
@@ -1211,24 +1196,13 @@ INSTANTIATE_TEST_SUITE_P(
{
// original
{
- "%spec_v2uint_zero = OpSpecConstantOp %v2uint UConvert %bool_false_vec",
- "%spec_v2uint_one = OpSpecConstantOp %v2uint UConvert %bool_true_vec",
"%spec_v2ulong_zero = OpSpecConstantOp %v2ulong UConvert %unsigned_zero_vec",
"%spec_v2ulong_one = OpSpecConstantOp %v2ulong UConvert %unsigned_one_vec",
},
// expected
{
- "%uint_0 = OpConstant %uint 0",
- "%uint_0_0 = OpConstant %uint 0",
- "%spec_v2uint_zero = OpConstantComposite %v2uint %unsigned_zero %unsigned_zero",
- "%uint_1 = OpConstant %uint 1",
- "%uint_1_0 = OpConstant %uint 1",
- "%spec_v2uint_one = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
- "%ulong_0 = OpConstant %ulong 0",
- "%ulong_0_0 = OpConstant %ulong 0",
"%spec_v2ulong_zero = OpConstantComposite %v2ulong %ulong_zero %ulong_zero",
"%ulong_1 = OpConstant %ulong 1",
- "%ulong_1_0 = OpConstant %ulong 1",
"%spec_v2ulong_one = OpConstantComposite %v2ulong %ulong_1 %ulong_1",
},
},
@@ -1243,14 +1217,10 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%long_0 = OpConstant %long 0",
- "%long_0_0 = OpConstant %long 0",
"%spec_v2long_zero = OpConstantComposite %v2long %long_zero %long_zero",
"%long_1 = OpConstant %long 1",
- "%long_1_0 = OpConstant %long 1",
"%spec_v2long_one = OpConstantComposite %v2long %long_1 %long_1",
"%long_n1 = OpConstant %long -1",
- "%long_n1_0 = OpConstant %long -1",
"%spec_v2long_minus_one = OpConstantComposite %v2long %long_n1 %long_n1",
},
},
@@ -1347,7 +1317,7 @@ INSTANTIATE_TEST_SUITE_P(
{
"%int_minus_1 = OpConstant %int -1",
"%int_minus_2 = OpConstant %int -2",
- "%int_neg_null = OpConstant %int 0",
+ "%int_neg_null = OpConstantNull %int",
"%int_max = OpConstant %int 2147483647",
"%int_neg_max = OpConstant %int -2147483647",
},
@@ -1528,15 +1498,10 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%int_n1 = OpConstant %int -1",
- "%int_n1_0 = OpConstant %int -1",
"%v2int_minus_1 = OpConstantComposite %v2int %signed_minus_one %signed_minus_one",
"%int_n2 = OpConstant %int -2",
- "%int_n2_0 = OpConstant %int -2",
"%v2int_minus_2 = OpConstantComposite %v2int %int_n2 %int_n2",
- "%int_0 = OpConstant %int 0",
- "%int_0_0 = OpConstant %int 0",
- "%v2int_neg_null = OpConstantComposite %v2int %signed_zero %signed_zero",
+ "%v2int_neg_null = OpConstantComposite %v2int %signed_null %signed_null",
},
},
// vector integer (including null vetors) add, sub, div, mul
@@ -1558,35 +1523,23 @@ INSTANTIATE_TEST_SUITE_P(
// expected
{
"%int_5 = OpConstant %int 5",
- "%int_5_0 = OpConstant %int 5",
"%spec_v2int_iadd = OpConstantComposite %v2int %int_5 %int_5",
"%int_n4 = OpConstant %int -4",
- "%int_n4_0 = OpConstant %int -4",
"%spec_v2int_isub = OpConstantComposite %v2int %int_n4 %int_n4",
"%int_n2 = OpConstant %int -2",
- "%int_n2_0 = OpConstant %int -2",
"%spec_v2int_sdiv = OpConstantComposite %v2int %int_n2 %int_n2",
"%int_n6 = OpConstant %int -6",
- "%int_n6_0 = OpConstant %int -6",
"%spec_v2int_imul = OpConstantComposite %v2int %int_n6 %int_n6",
- "%int_n6_1 = OpConstant %int -6",
- "%int_n6_2 = OpConstant %int -6",
"%spec_v2int_iadd_null = OpConstantComposite %v2int %int_n6 %int_n6",
"%uint_5 = OpConstant %uint 5",
- "%uint_5_0 = OpConstant %uint 5",
"%spec_v2uint_iadd = OpConstantComposite %v2uint %uint_5 %uint_5",
"%uint_4294967292 = OpConstant %uint 4294967292",
- "%uint_4294967292_0 = OpConstant %uint 4294967292",
"%spec_v2uint_isub = OpConstantComposite %v2uint %uint_4294967292 %uint_4294967292",
"%uint_1431655764 = OpConstant %uint 1431655764",
- "%uint_1431655764_0 = OpConstant %uint 1431655764",
"%spec_v2uint_udiv = OpConstantComposite %v2uint %uint_1431655764 %uint_1431655764",
"%uint_2863311528 = OpConstant %uint 2863311528",
- "%uint_2863311528_0 = OpConstant %uint 2863311528",
"%spec_v2uint_imul = OpConstantComposite %v2uint %uint_2863311528 %uint_2863311528",
- "%uint_2863311528_1 = OpConstant %uint 2863311528",
- "%uint_2863311528_2 = OpConstant %uint 2863311528",
"%spec_v2uint_isub_null = OpConstantComposite %v2uint %uint_2863311528 %uint_2863311528",
},
},
@@ -1630,34 +1583,17 @@ INSTANTIATE_TEST_SUITE_P(
"%v2int_minus_3 = OpConstantComposite %v2int %int_minus_3 %int_minus_3",
// srem
- "%int_1 = OpConstant %int 1",
- "%int_1_0 = OpConstant %int 1",
"%7_srem_3 = OpConstantComposite %v2int %signed_one %signed_one",
- "%int_n1 = OpConstant %int -1",
- "%int_n1_0 = OpConstant %int -1",
"%minus_7_srem_3 = OpConstantComposite %v2int %signed_minus_one %signed_minus_one",
- "%int_1_1 = OpConstant %int 1",
- "%int_1_2 = OpConstant %int 1",
"%7_srem_minus_3 = OpConstantComposite %v2int %signed_one %signed_one",
- "%int_n1_1 = OpConstant %int -1",
- "%int_n1_2 = OpConstant %int -1",
"%minus_7_srem_minus_3 = OpConstantComposite %v2int %signed_minus_one %signed_minus_one",
// smod
- "%int_1_3 = OpConstant %int 1",
- "%int_1_4 = OpConstant %int 1",
"%7_smod_3 = OpConstantComposite %v2int %signed_one %signed_one",
- "%int_2 = OpConstant %int 2",
- "%int_2_0 = OpConstant %int 2",
"%minus_7_smod_3 = OpConstantComposite %v2int %signed_two %signed_two",
"%int_n2 = OpConstant %int -2",
- "%int_n2_0 = OpConstant %int -2",
"%7_smod_minus_3 = OpConstantComposite %v2int %int_n2 %int_n2",
- "%int_n1_3 = OpConstant %int -1",
- "%int_n1_4 = OpConstant %int -1",
"%minus_7_smod_minus_3 = OpConstantComposite %v2int %signed_minus_one %signed_minus_one",
// umod
- "%uint_1 = OpConstant %uint 1",
- "%uint_1_0 = OpConstant %uint 1",
"%7_umod_3 = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
},
},
@@ -1677,26 +1613,15 @@ INSTANTIATE_TEST_SUITE_P(
},
// expected
{
- "%int_2 = OpConstant %int 2",
- "%int_2_0 = OpConstant %int 2",
"%xor_1_3 = OpConstantComposite %v2int %signed_two %signed_two",
- "%int_0 = OpConstant %int 0",
- "%int_0_0 = OpConstant %int 0",
"%and_1_2 = OpConstantComposite %v2int %signed_zero %signed_zero",
- "%int_3 = OpConstant %int 3",
- "%int_3_0 = OpConstant %int 3",
"%or_1_2 = OpConstantComposite %v2int %signed_three %signed_three",
"%unsigned_31 = OpConstant %uint 31",
"%v2unsigned_31 = OpConstantComposite %v2uint %unsigned_31 %unsigned_31",
"%uint_2147483648 = OpConstant %uint 2147483648",
- "%uint_2147483648_0 = OpConstant %uint 2147483648",
"%unsigned_left_shift_max = OpConstantComposite %v2uint %uint_2147483648 %uint_2147483648",
- "%uint_1 = OpConstant %uint 1",
- "%uint_1_0 = OpConstant %uint 1",
"%unsigned_right_shift_logical = OpConstantComposite %v2uint %unsigned_one %unsigned_one",
- "%int_n1 = OpConstant %int -1",
- "%int_n1_0 = OpConstant %int -1",
"%signed_right_shift_arithmetic = OpConstantComposite %v2int %signed_minus_one %signed_minus_one",
},
},
@@ -2066,7 +1991,6 @@ INSTANTIATE_TEST_SUITE_P(
"%spec_int_20 = OpConstant %int 101",
"%used_vec_a = OpConstantComposite %v2int %spec_int_18 %spec_int_19",
"%int_10201 = OpConstant %int 10201",
- "%int_1 = OpConstant %int 1",
"%used_vec_b = OpConstantComposite %v2int %int_10201 %signed_one",
"%spec_int_21 = OpConstant %int 10201",
"%array = OpConstantComposite %type_arr_int_4 %spec_int_20 %spec_int_20 %spec_int_21 %spec_int_21",
diff --git a/third_party/SPIRV-Tools/test/opt/fold_test.cpp b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
index eff8edf0a..a4e0447c1 100644
--- a/third_party/SPIRV-Tools/test/opt/fold_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/fold_test.cpp
@@ -16,7 +16,6 @@
#include <limits>
#include <memory>
#include <string>
-#include <unordered_set>
#include <vector>
#include "effcee/effcee.h"
@@ -67,44 +66,138 @@ struct InstructionFoldingCase {
ResultType expected_result;
};
-using IntegerInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
-
-TEST_P(IntegerInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
-
+std::tuple<std::unique_ptr<IRContext>, Instruction*> GetInstructionToFold(
+ const std::string test_body, const uint32_t id_to_fold,
+ spv_target_env spv_env) {
// Build module.
std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
+ BuildModule(spv_env, nullptr, test_body,
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ EXPECT_NE(nullptr, context);
+ if (context == nullptr) {
+ return {nullptr, nullptr};
+ }
// Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+ if (id_to_fold != 0) {
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ Instruction* inst = def_use_mgr->GetDef(id_to_fold);
+ return {std::move(context), inst};
+ }
+
+ // If there is not ID, we get the instruction just before a terminator
+ // instruction. That could be a return or abort. This is used for cases where
+ // the instruction we want to fold does not have a result id.
+ Function* func = &*context->module()->begin();
+ for (auto& bb : *func) {
+ Instruction* terminator = bb.terminator();
+ if (terminator->IsReturnOrAbort()) {
+ return {std::move(context), terminator->PreviousNode()};
+ }
+ }
+ return {nullptr, nullptr};
+}
+
+std::tuple<std::unique_ptr<IRContext>, Instruction*> FoldInstruction(
+ const std::string test_body, const uint32_t id_to_fold,
+ spv_target_env spv_env) {
+ // Build module.
+ std::unique_ptr<IRContext> context;
+ Instruction* inst = nullptr;
+ std::tie(context, inst) =
+ GetInstructionToFold(test_body, id_to_fold, spv_env);
+
+ if (context == nullptr) {
+ return {nullptr, nullptr};
+ }
+
+ std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
+ EXPECT_EQ(inst->result_id(), original_inst->result_id());
+ EXPECT_EQ(inst->type_id(), original_inst->type_id());
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
+ if (!succeeded && inst != nullptr) {
+ EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands());
+ for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
+ EXPECT_EQ(inst->GetOperand(i), original_inst->GetOperand(i));
+ }
+ }
+
+ return {std::move(context), succeeded ? inst : nullptr};
+}
+
+template <class ElementType, class Function>
+void CheckForExpectedScalarConstant(Instruction* inst,
+ ElementType expected_result,
+ Function GetValue) {
+ ASSERT_TRUE(inst);
+
+ IRContext* context = inst->context();
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ while (inst->opcode() == spv::Op::OpCopyObject) {
inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), spv::Op::OpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* constant = const_mrg->GetConstantFromInst(inst);
- // We expect to see either integer types or 16-bit float types here.
- EXPECT_TRUE((constant->AsIntConstant() != nullptr) ||
- ((constant->AsFloatConstant() != nullptr) &&
- (constant->type()->AsFloat()->width() == 16)));
- const analysis::ScalarConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsScalarConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetU32BitValue(), tc.expected_result);
+ }
+
+ // Make sure we have a constant.
+ analysis::ConstantManager* const_mrg = context->get_constant_mgr();
+ const analysis::Constant* constant = const_mrg->GetConstantFromInst(inst);
+ ASSERT_TRUE(constant);
+
+ // Make sure the constant is a scalar.
+ const analysis::ScalarConstant* result = constant->AsScalarConstant();
+ ASSERT_TRUE(result);
+
+ // Check if the result matches the expected value.
+ // If ExpectedType is not a float type, it should cast the value to a double
+ // and never get a nan.
+ if (!std::isnan(static_cast<double>(expected_result))) {
+ EXPECT_EQ(expected_result, GetValue(result));
+ } else {
+ EXPECT_TRUE(std::isnan(static_cast<double>(GetValue(result))));
+ }
+}
+
+template <class ElementType, class Function>
+void CheckForExpectedVectorConstant(Instruction* inst,
+ std::vector<ElementType> expected_result,
+ Function GetValue) {
+ ASSERT_TRUE(inst);
+
+ IRContext* context = inst->context();
+ EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
+ std::vector<spv::Op> opcodes = {spv::Op::OpConstantComposite};
+ EXPECT_THAT(opcodes, Contains(inst->opcode()));
+ analysis::ConstantManager* const_mrg = context->get_constant_mgr();
+ const analysis::Constant* result = const_mrg->GetConstantFromInst(inst);
+ EXPECT_NE(result, nullptr);
+ if (result != nullptr) {
+ const std::vector<const analysis::Constant*>& componenets =
+ result->AsVectorConstant()->GetComponents();
+ EXPECT_EQ(componenets.size(), expected_result.size());
+ for (size_t i = 0; i < componenets.size(); i++) {
+ EXPECT_EQ(expected_result[i], GetValue(componenets[i]));
}
}
}
+using IntegerInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<uint32_t>>;
+
+TEST_P(IntegerInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedScalarConstant(
+ inst, tc.expected_result, [](const analysis::Constant* c) {
+ return c->AsScalarConstant()->GetU32BitValue();
+ });
+}
+
// Returns a common SPIR-V header for all of the test that follow.
#define INT_0_ID 100
#define TRUE_ID 101
@@ -148,14 +241,20 @@ OpName %main "main"
%ulong = OpTypeInt 64 0
%v2int = OpTypeVector %int 2
%v4int = OpTypeVector %int 4
+%v2short = OpTypeVector %short 2
+%v2long = OpTypeVector %long 2
+%v4long = OpTypeVector %long 4
%v4float = OpTypeVector %float 4
%v4double = OpTypeVector %double 4
%v2uint = OpTypeVector %uint 2
+%v2ulong = OpTypeVector %ulong 2
%v2float = OpTypeVector %float 2
%v2double = OpTypeVector %double 2
%v2half = OpTypeVector %half 2
%v2bool = OpTypeVector %bool 2
%m2x2int = OpTypeMatrix %v2int 2
+%mat4v2float = OpTypeMatrix %v2float 4
+%mat2v4float = OpTypeMatrix %v4float 2
%mat4v4float = OpTypeMatrix %v4float 4
%mat4v4double = OpTypeMatrix %v4double 4
%struct_v2int_int_int = OpTypeStruct %v2int %int %int
@@ -174,16 +273,18 @@ OpName %main "main"
%_ptr_struct_v2int_int_int = OpTypePointer Function %struct_v2int_int_int
%_ptr_v2float = OpTypePointer Function %v2float
%_ptr_v2double = OpTypePointer Function %v2double
+%int_2 = OpConstant %int 2
+%int_arr_2 = OpTypeArray %int %int_2
%short_0 = OpConstant %short 0
%short_2 = OpConstant %short 2
%short_3 = OpConstant %short 3
+%short_n5 = OpConstant %short -5
%ubyte_1 = OpConstant %ubyte 1
%byte_n1 = OpConstant %byte -1
%100 = OpConstant %int 0 ; Need a def with an numerical id to define id maps.
%103 = OpConstant %int 7 ; Need a def with an numerical id to define id maps.
%int_0 = OpConstant %int 0
%int_1 = OpConstant %int 1
-%int_2 = OpConstant %int 2
%int_3 = OpConstant %int 3
%int_4 = OpConstant %int 4
%int_10 = OpConstant %int 10
@@ -197,12 +298,20 @@ OpName %main "main"
%long_1 = OpConstant %long 1
%long_2 = OpConstant %long 2
%long_3 = OpConstant %long 3
+%long_n3 = OpConstant %long -3
+%long_7 = OpConstant %long 7
+%long_n7 = OpConstant %long -7
%long_10 = OpConstant %long 10
+%long_32768 = OpConstant %long 32768
+%long_n57344 = OpConstant %long -57344
+%long_n4611686018427387904 = OpConstant %long -4611686018427387904
%long_4611686018427387904 = OpConstant %long 4611686018427387904
%long_n1 = OpConstant %long -1
%long_n3689348814741910323 = OpConstant %long -3689348814741910323
%long_min = OpConstant %long -9223372036854775808
%long_max = OpConstant %long 9223372036854775807
+%ulong_7 = OpConstant %ulong 7
+%ulong_4611686018427387904 = OpConstant %ulong 4611686018427387904
%uint_0 = OpConstant %uint 0
%uint_1 = OpConstant %uint 1
%uint_2 = OpConstant %uint 2
@@ -223,8 +332,12 @@ OpName %main "main"
%v2int_2_2 = OpConstantComposite %v2int %int_2 %int_2
%v2int_2_3 = OpConstantComposite %v2int %int_2 %int_3
%v2int_3_2 = OpConstantComposite %v2int %int_3 %int_2
+%v2int_n1_n24 = OpConstantComposite %v2int %int_n1 %int_n24
%v2int_4_4 = OpConstantComposite %v2int %int_4 %int_4
%v2int_min_max = OpConstantComposite %v2int %int_min %int_max
+%v2short_2_n5 = OpConstantComposite %v2short %short_2 %short_n5
+%v2long_2_2 = OpConstantComposite %v2long %long_2 %long_2
+%v2long_2_3 = OpConstantComposite %v2long %long_2 %long_3
%v2bool_null = OpConstantNull %v2bool
%v2bool_true_false = OpConstantComposite %v2bool %true %false
%v2bool_false_true = OpConstantComposite %v2bool %false %true
@@ -282,6 +395,7 @@ OpName %main "main"
%v2double_null = OpConstantNull %v2double
%108 = OpConstant %half 0
%half_1 = OpConstant %half 1
+%half_2 = OpConstant %half 2
%half_0_1 = OpConstantComposite %v2half %108 %half_1
%106 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
%v4float_0_0_0_0 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_0
@@ -290,7 +404,8 @@ OpName %main "main"
%v4float_1_1_1_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1
%v4float_1_2_3_4 = OpConstantComposite %v4float %float_1 %float_2 %float_3 %float_4
%v4float_null = OpConstantNull %v4float
-%mat4v4float_null = OpConstantComposite %mat4v4float %v4float_null %v4float_null %v4float_null %v4float_null
+%mat2v4float_null = OpConstantNull %mat2v4float
+%mat4v4float_null = OpConstantNull %mat4v4float
%mat4v4float_1_2_3_4 = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4 %v4float_1_2_3_4
%mat4v4float_1_2_3_4_null = OpConstantComposite %mat4v4float %v4float_1_2_3_4 %v4float_null %v4float_1_2_3_4 %v4float_null
%107 = OpConstantComposite %v4double %double_0 %double_0 %double_0 %double_0
@@ -301,7 +416,7 @@ OpName %main "main"
%v4double_1_2_3_4 = OpConstantComposite %v4double %double_1 %double_2 %double_3 %double_4
%v4double_1_1_1_0p5 = OpConstantComposite %v4double %double_1 %double_1 %double_1 %double_0p5
%v4double_null = OpConstantNull %v4double
-%mat4v4double_null = OpConstantComposite %mat4v4double %v4double_null %v4double_null %v4double_null %v4double_null
+%mat4v4double_null = OpConstantNull %mat4v4double
%mat4v4double_1_2_3_4 = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4 %v4double_1_2_3_4
%mat4v4double_1_2_3_4_null = OpConstantComposite %mat4v4double %v4double_1_2_3_4 %v4double_null %v4double_1_2_3_4 %v4double_null
%v4float_n1_2_1_3 = OpConstantComposite %v4float %float_n1 %float_2 %float_1 %float_3
@@ -314,8 +429,11 @@ OpName %main "main"
%int_0xC05FD666 = OpConstant %int 0xC05FD666
%int_0x66666666 = OpConstant %int 0x66666666
%v4int_0x3FF00000_0x00000000_0xC05FD666_0x66666666 = OpConstantComposite %v4int %int_0x00000000 %int_0x3FF00000 %int_0x66666666 %int_0xC05FD666
+%ushort_0x4400 = OpConstant %ushort 0x4400
+%short_0x4400 = OpConstant %short 0x4400
%ushort_0xBC00 = OpConstant %ushort 0xBC00
%short_0xBC00 = OpConstant %short 0xBC00
+%int_arr_2_undef = OpUndef %int_arr_2
)";
return header;
@@ -749,7 +867,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 1),
- // Test case 44: UClamp 1 2 x
+ // Test case 46: UClamp 1 2 x
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -758,7 +876,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 2),
- // Test case 45: UClamp 2 x 1
+ // Test case 47: UClamp 2 x 1
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -767,7 +885,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 1),
- // Test case 46: Bit-cast int 0 to unsigned int
+ // Test case 48: Bit-cast int 0 to unsigned int
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -775,7 +893,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0),
- // Test case 47: Bit-cast int -24 to unsigned int
+ // Test case 49: Bit-cast int -24 to unsigned int
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -783,7 +901,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, static_cast<uint32_t>(-24)),
- // Test case 48: Bit-cast float 1.0f to unsigned int
+ // Test case 50: Bit-cast float 1.0f to unsigned int
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -791,7 +909,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, static_cast<uint32_t>(0x3f800000)),
- // Test case 49: Bit-cast ushort 0xBC00 to ushort
+ // Test case 51: Bit-cast ushort 0xBC00 to ushort
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -799,7 +917,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xBC00),
- // Test case 50: Bit-cast short 0xBC00 to ushort
+ // Test case 52: Bit-cast short 0xBC00 to ushort
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -807,7 +925,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xFFFFBC00),
- // Test case 51: Bit-cast half 1 to ushort
+ // Test case 53: Bit-cast half 1 to ushort
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -815,7 +933,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0x3C00),
- // Test case 52: Bit-cast ushort 0xBC00 to short
+ // Test case 54: Bit-cast ushort 0xBC00 to short
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -823,7 +941,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xBC00),
- // Test case 53: Bit-cast short 0xBC00 to short
+ // Test case 55: Bit-cast short 0xBC00 to short
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -831,7 +949,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xFFFFBC00),
- // Test case 54: Bit-cast half 1 to short
+ // Test case 56: Bit-cast half 1 to short
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -839,7 +957,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0x3C00),
- // Test case 55: Bit-cast ushort 0xBC00 to half
+ // Test case 57: Bit-cast ushort 0xBC00 to half
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -847,7 +965,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xBC00),
- // Test case 56: Bit-cast short 0xBC00 to half
+ // Test case 58: Bit-cast short 0xBC00 to half
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -855,7 +973,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0xFFFFBC00),
- // Test case 57: Bit-cast half 1 to half
+ // Test case 59: Bit-cast half 1 to half
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -863,7 +981,7 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 0x3C00),
- // Test case 58: Bit-cast ubyte 1 to byte
+ // Test case 60: Bit-cast ubyte 1 to byte
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -871,58 +989,302 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, 1),
- // Test case 59: Bit-cast byte -1 to ubyte
+ // Test case 61: Bit-cast byte -1 to ubyte
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
"%2 = OpBitcast %ubyte %byte_n1\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 2, 0xFFFFFFFF)
+ 2, 0xFFFFFFFF),
+ // Test case 62: Negate 2.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %int %int_2\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -2),
+ // Test case 63: Negate negative short.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %short %short_0xBC00\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0x4400 /* expected to be sign extended. */),
+ // Test case 64: Negate positive short.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %short %short_0x4400\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0xFFFFBC00 /* expected to be sign extended. */),
+ // Test case 65: Negate a negative short.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %ushort %ushort_0xBC00\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0x4400 /* expected to be zero extended. */),
+ // Test case 66: Negate positive short.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %ushort %ushort_0x4400\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0xBC00 /* expected to be zero extended. */),
+ // Test case 67: Fold 2 + 3 (short)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpIAdd %short %short_2 %short_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 5),
+ // Test case 68: Fold 2 + -5 (short)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpIAdd %short %short_2 %short_n5\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -3),
+ // Test case 69: Fold int(3ll)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSConvert %int %long_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 3),
+ // Test case 70: Fold short(-3ll)
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSConvert %short %long_n3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -3),
+ // Test case 71: Fold short(32768ll) - This should do a sign extend when
+ // converting to short.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSConvert %short %long_32768\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -32768),
+ // Test case 72: Fold short(-57344) - This should do a sign extend when
+ // converting to short making the upper bits 0.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSConvert %short %long_n57344\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 8192),
+ // Test case 73: Fold int(-5(short)). The -5 should be interpreted as an unsigned value, and be zero extended to 32-bits.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpUConvert %uint %short_n5\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 65531),
+ // Test case 74: Fold short(-24(int)). The upper bits should be cleared. So 0xFFFFFFE8 should become 0x0000FFE8.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpUConvert %ushort %int_n24\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 65512)
));
// clang-format on
-using IntVectorInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint32_t>>>;
+using LongIntegerInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<uint64_t>>;
-TEST_P(IntVectorInstructionFoldingTest, Case) {
+TEST_P(LongIntegerInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedScalarConstant(
+ inst, tc.expected_result, [](const analysis::Constant* c) {
+ return c->AsScalarConstant()->GetU64BitValue();
+ });
+}
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- spv::Op original_opcode = inst->opcode();
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
+INSTANTIATE_TEST_SUITE_P(
+ TestCase, LongIntegerInstructionFoldingTest,
+ ::testing::Values(
+ // Test case 0: fold 1+4611686018427387904
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpIAdd %long %long_1 %long_4611686018427387904\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 1 + 4611686018427387904),
+ // Test case 1: fold 1-4611686018427387904
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpISub %long %long_1 %long_4611686018427387904\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 1 - 4611686018427387904),
+ // Test case 2: fold 2*4611686018427387904
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpIMul %long %long_2 %long_4611686018427387904\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 9223372036854775808ull),
+ // Test case 3: fold 4611686018427387904/2 (unsigned)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpUDiv %ulong %ulong_4611686018427387904 %ulong_2\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 4611686018427387904 / 2),
+ // Test case 4: fold 4611686018427387904/2 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSDiv %long %long_4611686018427387904 %long_2\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 4611686018427387904 / 2),
+ // Test case 5: fold -4611686018427387904/2 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSDiv %long %long_n4611686018427387904 %long_2\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, -4611686018427387904 / 2),
+ // Test case 6: fold 4611686018427387904 mod 7 (unsigned)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpUMod %ulong %ulong_4611686018427387904 %ulong_7\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 4611686018427387904ull % 7ull),
+ // Test case 7: fold 7 mod 3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSMod %long %long_7 %long_3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 1ull),
+ // Test case 8: fold 7 rem 3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSRem %long %long_7 %long_3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 1ull),
+ // Test case 9: fold 7 mod -3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSMod %long %long_7 %long_n3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -2ll),
+ // Test case 10: fold 7 rem 3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSRem %long %long_7 %long_n3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 1ll),
+ // Test case 11: fold -7 mod 3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSMod %long %long_n7 %long_3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 2ll),
+ // Test case 12: fold -7 rem 3 (signed)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSRem %long %long_n7 %long_3\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -1ll),
+ // Test case 13: fold long(-24)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSConvert %long %int_n24\n" + "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, -24ll),
+ // Test case 14: fold long(-24)
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" + "%2 = OpSConvert %long %int_10\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 10ll),
+ // Test case 15: fold long(-24(short)).
+ // The upper bits should be cleared. So 0xFFFFFFE8 should become
+ // 0x000000000000FFE8.
+ InstructionFoldingCase<uint64_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" + "%2 = OpUConvert %ulong %short_n5\n" +
+ "OpReturn\n" + "OpFunctionEnd",
+ 2, 65531ull)));
- // Make sure the instruction folded as expected.
- EXPECT_EQ(succeeded, inst == nullptr || inst->opcode() != original_opcode);
- if (succeeded && inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<spv::Op> opcodes = {spv::Op::OpConstantComposite};
- EXPECT_THAT(opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* result = const_mrg->GetConstantFromInst(inst);
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- const std::vector<const analysis::Constant*>& componenets =
- result->AsVectorConstant()->GetComponents();
- EXPECT_EQ(componenets.size(), tc.expected_result.size());
- for (size_t i = 0; i < componenets.size(); i++) {
- EXPECT_EQ(tc.expected_result[i], componenets[i]->GetU32());
- }
- }
- }
+using UIntVectorInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint32_t>>>;
+
+TEST_P(UIntVectorInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedVectorConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->GetU32(); });
}
// clang-format off
-INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest,
+INSTANTIATE_TEST_SUITE_P(TestCase, UIntVectorInstructionFoldingTest,
::testing::Values(
// Test case 0: fold 0*n
InstructionFoldingCase<std::vector<uint32_t>>(
@@ -943,73 +1305,165 @@ INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest,
"OpReturn\n" +
"OpFunctionEnd",
2, {0,3}),
+ // Test case 4: fold bit-cast int -24 to unsigned int
InstructionFoldingCase<std::vector<uint32_t>>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
"%n = OpVariable %_ptr_int Function\n" +
"%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 4294967295 3\n" +
+ "%2 = OpBitcast %v2uint %v2int_min_max\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 2, {0,0}),
+ 2, {2147483648, 2147483647}),
+ // Test case 5: fold SNegate vector of uint
InstructionFoldingCase<std::vector<uint32_t>>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
"%n = OpVariable %_ptr_int Function\n" +
"%load = OpLoad %int %n\n" +
- "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 0 4294967295 \n" +
+ "%2 = OpSNegate %v2uint %v2uint_0x3f800000_0xbf800000\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 2, {0,0}),
- // Test case 4: fold bit-cast int -24 to unsigned int
+ 2, {static_cast<uint32_t>(-0x3f800000), static_cast<uint32_t>(-0xbf800000)}),
+ // Test case 6: fold vector components of uint (including integer overflow)
InstructionFoldingCase<std::vector<uint32_t>>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
- "%n = OpVariable %_ptr_int Function\n" +
- "%load = OpLoad %int %n\n" +
- "%2 = OpBitcast %v2uint %v2int_min_max\n" +
+ "%2 = OpIAdd %v2uint %v2uint_0x3f800000_0xbf800000 %v2uint_0x3f800000_0xbf800000\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 2, {2147483648, 2147483647})
+ 2, {0x7f000000u, 0x7f000000u}),
+ // Test case 6: fold vector components of uint
+ InstructionFoldingCase<std::vector<uint32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSConvert %v2int %v2short_2_n5\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {2,static_cast<uint32_t>(-5)}),
+ // Test case 6: fold vector components of uint (incuding integer overflow)
+ InstructionFoldingCase<std::vector<uint32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpUConvert %v2uint %v2short_2_n5\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {2,65531})
));
// clang-format on
+using IntVectorInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<std::vector<int32_t>>>;
+
+TEST_P(IntVectorInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+
+ CheckForExpectedVectorConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->GetS32(); });
+}
+
+// clang-format off
+INSTANTIATE_TEST_SUITE_P(TestCase, IntVectorInstructionFoldingTest,
+::testing::Values(
+ // Test case 0: fold negate of a vector
+ InstructionFoldingCase<std::vector<int32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %v2int %v2int_2_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {-2, -3}),
+ // Test case 1: fold negate of a vector containing negative values.
+ InstructionFoldingCase<std::vector<int32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %v2int %v2int_n1_n24\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {1, 24}),
+ // Test case 2: fold negate of a vector at the limits
+ InstructionFoldingCase<std::vector<int32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpSNegate %v2int %v2int_min_max\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {INT_MIN, -INT_MAX}),
+ // Test case 3: fold vector components of int
+ InstructionFoldingCase<std::vector<int32_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpIMul %v2int %v2int_2_3 %v2int_2_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {4,9})
+));
+// clang-format on
+
+using LongIntVectorInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<std::vector<uint64_t>>>;
+
+TEST_P(LongIntVectorInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedVectorConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->GetU64(); });
+}
+
+// clang-format off
+INSTANTIATE_TEST_SUITE_P(TestCase, LongIntVectorInstructionFoldingTest,
+ ::testing::Values(
+ // Test case 0: fold {2,2} + {2,3} (Testing that the vector logic works
+ // correctly. Scalar tests will check that the 64-bit values are correctly
+ // folded.)
+ InstructionFoldingCase<std::vector<uint64_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpIAdd %v2long %v2long_2_2 %v2long_2_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {4,5}),
+ // Test case 0: fold {2,2} / {2,3} (Testing that the vector logic works
+ // correctly. Scalar tests will check that the 64-bit values are correctly
+ // folded.)
+ InstructionFoldingCase<std::vector<uint64_t>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpSDiv %v2long %v2long_2_2 %v2long_2_3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {1,0})
+ ));
+// clang-format on
+
using DoubleVectorInstructionFoldingTest =
::testing::TestWithParam<InstructionFoldingCase<std::vector<double>>>;
TEST_P(DoubleVectorInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
-
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (succeeded && inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<spv::Op> opcodes = {spv::Op::OpConstantComposite};
- EXPECT_THAT(opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* result = const_mrg->GetConstantFromInst(inst);
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- const std::vector<const analysis::Constant*>& componenets =
- result->AsVectorConstant()->GetComponents();
- EXPECT_EQ(componenets.size(), tc.expected_result.size());
- for (size_t i = 0; i < componenets.size(); i++) {
- EXPECT_EQ(tc.expected_result[i], componenets[i]->GetDouble());
- }
- }
- }
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedVectorConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->GetDouble(); });
}
// clang-format off
@@ -1104,37 +1558,10 @@ using FloatVectorInstructionFoldingTest =
TEST_P(FloatVectorInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- spv::Op original_opcode = inst->opcode();
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
-
- // Make sure the instruction folded as expected.
- EXPECT_EQ(succeeded, inst == nullptr || inst->opcode() != original_opcode);
- if (succeeded && inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<spv::Op> opcodes = {spv::Op::OpConstantComposite};
- EXPECT_THAT(opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::Constant* result = const_mrg->GetConstantFromInst(inst);
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- const std::vector<const analysis::Constant*>& componenets =
- result->AsVectorConstant()->GetComponents();
- EXPECT_EQ(componenets.size(), tc.expected_result.size());
- for (size_t i = 0; i < componenets.size(); i++) {
- EXPECT_EQ(tc.expected_result[i], componenets[i]->GetFloat());
- }
- }
- }
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedVectorConstant(inst, tc.expected_result, [](const analysis::Constant* c){ return c->GetFloat();});
}
// clang-format off
@@ -1239,42 +1666,92 @@ INSTANTIATE_TEST_SUITE_P(TestCase, FloatVectorInstructionFoldingTest,
2, {4.0,8.0,12.0,16.0})
));
// clang-format on
-using BooleanInstructionFoldingTest =
- ::testing::TestWithParam<InstructionFoldingCase<bool>>;
-TEST_P(BooleanInstructionFoldingTest, Case) {
- const auto& tc = GetParam();
+using FloatMatrixInstructionFoldingTest = ::testing::TestWithParam<
+ InstructionFoldingCase<std::vector<std::vector<float>>>>;
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+TEST_P(FloatMatrixInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
+ EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
+ if (inst->opcode() == spv::Op::OpCopyObject) {
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- std::vector<spv::Op> bool_opcodes = {spv::Op::OpConstantTrue,
- spv::Op::OpConstantFalse};
- EXPECT_THAT(bool_opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::BoolConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsBoolConstant();
+ analysis::ConstantManager* const_mgr = context->get_constant_mgr();
+ const analysis::Constant* result = const_mgr->GetConstantFromInst(inst);
EXPECT_NE(result, nullptr);
if (result != nullptr) {
- EXPECT_EQ(result->value(), tc.expected_result);
+ std::vector<const analysis::Constant*> matrix =
+ result->AsMatrixConstant()->GetComponents();
+ EXPECT_EQ(matrix.size(), tc.expected_result.size());
+ for (size_t c = 0; c < matrix.size(); c++) {
+ if (matrix[c]->AsNullConstant() != nullptr) {
+ matrix[c] = const_mgr->GetNullCompositeConstant(matrix[c]->type());
+ }
+ const analysis::VectorConstant* column_const =
+ matrix[c]->AsVectorConstant();
+ ASSERT_NE(column_const, nullptr);
+ const std::vector<const analysis::Constant*>& column =
+ column_const->GetComponents();
+ EXPECT_EQ(column.size(), tc.expected_result[c].size());
+ for (size_t r = 0; r < column.size(); r++) {
+ EXPECT_EQ(tc.expected_result[c][r], column[r]->GetFloat());
+ }
+ }
}
}
}
// clang-format off
+INSTANTIATE_TEST_SUITE_P(TestCase, FloatMatrixInstructionFoldingTest,
+::testing::Values(
+ // Test case 0: OpTranspose square null matrix
+ InstructionFoldingCase<std::vector<std::vector<float>>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpTranspose %mat4v4float %mat4v4float_null\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f},{0.0f, 0.0f, 0.0f, 0.0f}}),
+ // Test case 1: OpTranspose rectangular null matrix
+ InstructionFoldingCase<std::vector<std::vector<float>>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpTranspose %mat4v2float %mat2v4float_null\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f},{0.0f, 0.0f}}),
+ InstructionFoldingCase<std::vector<std::vector<float>>>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%2 = OpTranspose %mat4v4float %mat4v4float_1_2_3_4\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, {{1.0f, 1.0f, 1.0f, 1.0f},{2.0f, 2.0f, 2.0f, 2.0f},{3.0f, 3.0f, 3.0f, 3.0f},{4.0f, 4.0f, 4.0f, 4.0f}})
+));
+// clang-format on
+
+using BooleanInstructionFoldingTest =
+ ::testing::TestWithParam<InstructionFoldingCase<bool>>;
+
+TEST_P(BooleanInstructionFoldingTest, Case) {
+ const auto& tc = GetParam();
+
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedScalarConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->AsBoolConstant()->value(); });
+}
+
+// clang-format off
INSTANTIATE_TEST_SUITE_P(TestCase, BooleanInstructionFoldingTest,
::testing::Values(
// Test case 0: fold true || n
@@ -1857,35 +2334,15 @@ using FloatInstructionFoldingTest =
TEST_P(FloatInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), spv::Op::OpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::FloatConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsFloatConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- if (!std::isnan(tc.expected_result)) {
- EXPECT_EQ(result->GetFloatValue(), tc.expected_result);
- } else {
- EXPECT_TRUE(std::isnan(result->GetFloatValue()));
- }
- }
- }
+ CheckForExpectedScalarConstant(inst, tc.expected_result,
+ [](const analysis::Constant* c) {
+ return c->AsFloatConstant()->GetFloatValue();
+ });
}
// Not testing NaNs because there are no expectations concerning NaNs according
@@ -2290,35 +2747,14 @@ using DoubleInstructionFoldingTest =
TEST_P(DoubleInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
-
- // Make sure the instruction folded as expected.
- EXPECT_TRUE(succeeded);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
- inst = def_use_mgr->GetDef(inst->GetSingleWordInOperand(0));
- EXPECT_EQ(inst->opcode(), spv::Op::OpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::FloatConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsFloatConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- if (!std::isnan(tc.expected_result)) {
- EXPECT_EQ(result->GetDoubleValue(), tc.expected_result);
- } else {
- EXPECT_TRUE(std::isnan(result->GetDoubleValue()));
- }
- }
- }
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
+ CheckForExpectedScalarConstant(
+ inst, tc.expected_result, [](const analysis::Constant* c) {
+ return c->AsFloatConstant()->GetDoubleValue();
+ });
}
// clang-format off
@@ -3176,32 +3612,22 @@ using IntegerInstructionFoldingTestWithMap =
TEST_P(IntegerInstructionFoldingTestWithMap, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ GetInstructionToFold(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_5);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
tc.id_map);
-
- // Make sure the instruction folded as expected.
EXPECT_NE(inst, nullptr);
- if (inst != nullptr) {
- EXPECT_EQ(inst->opcode(), spv::Op::OpConstant);
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::IntConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsIntConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->GetU32BitValue(), tc.expected_result);
- }
- }
+
+ CheckForExpectedScalarConstant(inst, tc.expected_result,
+ [](const analysis::Constant* c) {
+ return c->AsIntConstant()->GetU32BitValue();
+ });
}
// clang-format off
+
INSTANTIATE_TEST_SUITE_P(TestCase, IntegerInstructionFoldingTestWithMap,
::testing::Values(
// Test case 0: fold %3 = 0; %3 * n
@@ -3224,32 +3650,16 @@ using BooleanInstructionFoldingTestWithMap =
TEST_P(BooleanInstructionFoldingTestWithMap, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ GetInstructionToFold(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_5);
inst = context->get_instruction_folder().FoldInstructionToConstant(inst,
tc.id_map);
-
- // Make sure the instruction folded as expected.
- EXPECT_NE(inst, nullptr);
- if (inst != nullptr) {
- std::vector<spv::Op> bool_opcodes = {spv::Op::OpConstantTrue,
- spv::Op::OpConstantFalse};
- EXPECT_THAT(bool_opcodes, Contains(inst->opcode()));
- analysis::ConstantManager* const_mrg = context->get_constant_mgr();
- const analysis::BoolConstant* result =
- const_mrg->GetConstantFromInst(inst)->AsBoolConstant();
- EXPECT_NE(result, nullptr);
- if (result != nullptr) {
- EXPECT_EQ(result->value(), tc.expected_result);
- }
- }
+ ASSERT_NE(inst, nullptr);
+ CheckForExpectedScalarConstant(
+ inst, tc.expected_result,
+ [](const analysis::Constant* c) { return c->AsBoolConstant()->value(); });
}
// clang-format off
@@ -3275,30 +3685,15 @@ using GeneralInstructionFoldingTest =
TEST_P(GeneralInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
-
- // Make sure the instruction folded as expected.
- EXPECT_EQ(inst->result_id(), original_inst->result_id());
- EXPECT_EQ(inst->type_id(), original_inst->type_id());
- EXPECT_TRUE((!succeeded) == (tc.expected_result == 0));
- if (succeeded) {
+ EXPECT_TRUE((inst == nullptr) == (tc.expected_result == 0));
+ if (inst != nullptr) {
EXPECT_EQ(inst->opcode(), spv::Op::OpCopyObject);
EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- } else {
- EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands());
- for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
- EXPECT_EQ(inst->GetOperand(i), original_inst->GetOperand(i));
- }
}
}
@@ -3725,23 +4120,7 @@ INSTANTIATE_TEST_SUITE_P(IntegerArithmeticTestCases, GeneralInstructionFoldingTe
"OpReturn\n" +
"OpFunctionEnd",
2, 0),
- // Test case 38: Don't fold 2 + 3 (long), bad length
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %long %long_2 %long_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 39: Don't fold 2 + 3 (short), bad length
- InstructionFoldingCase<uint32_t>(
- Header() + "%main = OpFunction %void None %void_func\n" +
- "%main_lab = OpLabel\n" +
- "%2 = OpIAdd %short %short_2 %short_3\n" +
- "OpReturn\n" +
- "OpFunctionEnd",
- 2, 0),
- // Test case 40: fold 1*n
+ // Test case 38: fold 1*n
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -3751,7 +4130,7 @@ INSTANTIATE_TEST_SUITE_P(IntegerArithmeticTestCases, GeneralInstructionFoldingTe
"OpReturn\n" +
"OpFunctionEnd",
2, 3),
- // Test case 41: fold n*1
+ // Test case 39: fold n*1
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
"%main_lab = OpLabel\n" +
@@ -3761,7 +4140,7 @@ INSTANTIATE_TEST_SUITE_P(IntegerArithmeticTestCases, GeneralInstructionFoldingTe
"OpReturn\n" +
"OpFunctionEnd",
2, 3),
- // Test case 42: Don't fold comparisons of 64-bit types
+ // Test case 40: Don't fold comparisons of 64-bit types
// (https://github.com/KhronosGroup/SPIRV-Tools/issues/3343).
InstructionFoldingCase<uint32_t>(
Header() + "%main = OpFunction %void None %void_func\n" +
@@ -4299,6 +4678,17 @@ INSTANTIATE_TEST_SUITE_P(FloatRedundantFoldingTest, GeneralInstructionFoldingTes
"%2 = OpDot %half %half_0_1 %half_0_1\n" +
"OpReturn\n" +
"OpFunctionEnd",
+ 2, 0),
+ // Test case 23: Don't fold 1.0(half) / 2.0(half)
+ // We do not have to code to emulate 16-bit float operations. Just make sure we do not crash.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_half Function\n" +
+ "%3 = OpLoad %half %n\n" +
+ "%2 = OpFDiv %half %half_1 %half_2\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
2, 0)
));
@@ -4611,7 +5001,31 @@ INSTANTIATE_TEST_SUITE_P(IntegerRedundantFoldingTest, GeneralInstructionFoldingT
"%2 = OpIAdd %v2int %v2int_0_0 %3\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 2, 3)
+ 2, 3),
+ // Test case 8: Don't fold because of undefined value. Using 4294967295
+ // means that entry is undefined. We do not expect it to ever happen, so
+ // not worth folding.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 4294967295 3\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0),
+ // Test case 9: Don't fold because of undefined value. Using 4294967295
+ // means that entry is undefined. We do not expect it to ever happen, so
+ // not worth folding.
+ InstructionFoldingCase<uint32_t>(
+ Header() + "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%n = OpVariable %_ptr_int Function\n" +
+ "%load = OpLoad %int %n\n" +
+ "%2 = OpVectorShuffle %v2int %v2int_null %v2int_2_3 0 4294967295 \n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 2, 0)
));
INSTANTIATE_TEST_SUITE_P(ClampAndCmpLHS, GeneralInstructionFoldingTest,
@@ -4933,30 +5347,15 @@ using ToNegateFoldingTest =
TEST_P(ToNegateFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
-
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) =
+ FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_1);
- // Make sure the instruction folded as expected.
- EXPECT_EQ(inst->result_id(), original_inst->result_id());
- EXPECT_EQ(inst->type_id(), original_inst->type_id());
- EXPECT_TRUE((!succeeded) == (tc.expected_result == 0));
- if (succeeded) {
+ EXPECT_TRUE((inst == nullptr) == (tc.expected_result == 0));
+ if (inst != nullptr) {
EXPECT_EQ(inst->opcode(), spv::Op::OpFNegate);
EXPECT_EQ(inst->GetSingleWordInOperand(0), tc.expected_result);
- } else {
- EXPECT_EQ(inst->NumInOperands(), original_inst->NumInOperands());
- for (uint32_t i = 0; i < inst->NumInOperands(); ++i) {
- EXPECT_EQ(inst->GetOperand(i), original_inst->GetOperand(i));
- }
}
}
@@ -5055,19 +5454,12 @@ using MatchingInstructionFoldingTest =
TEST_P(MatchingInstructionFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
+ EXPECT_EQ(inst != nullptr, tc.expected_result);
+ if (inst != nullptr) {
Match(tc.test_body, context.get());
}
}
@@ -7418,7 +7810,24 @@ INSTANTIATE_TEST_SUITE_P(CompositeExtractOrInsertMatchingTest, MatchingInstructi
"%4 = OpCompositeExtract %int %struct_v2int_int_int 3\n" +
"OpReturn\n" +
"OpFunctionEnd",
- 4, false)
+ 4, false),
+ // Test case 18: Fold when every element of an array is inserted.
+ InstructionFoldingCase<bool>(
+ Header() +
+ "; CHECK: [[int:%\\w+]] = OpTypeInt 32 1\n" +
+ "; CHECK: [[int2:%\\w+]] = OpConstant [[int]] 2\n" +
+ "; CHECK-DAG: [[arr_type:%\\w+]] = OpTypeArray [[int]] [[int2]]\n" +
+ "; CHECK-DAG: [[int10:%\\w+]] = OpConstant [[int]] 10\n" +
+ "; CHECK-DAG: [[int1:%\\w+]] = OpConstant [[int]] 1\n" +
+ "; CHECK: [[construct:%\\w+]] = OpCompositeConstruct [[arr_type]] [[int10]] [[int1]]\n" +
+ "; CHECK: %5 = OpCopyObject [[arr_type]] [[construct]]\n" +
+ "%main = OpFunction %void None %void_func\n" +
+ "%main_lab = OpLabel\n" +
+ "%4 = OpCompositeInsert %int_arr_2 %int_10 %int_arr_2_undef 0\n" +
+ "%5 = OpCompositeInsert %int_arr_2 %int_1 %4 1\n" +
+ "OpReturn\n" +
+ "OpFunctionEnd",
+ 5, true)
));
INSTANTIATE_TEST_SUITE_P(DotProductMatchingTest, MatchingInstructionFoldingTest,
@@ -7797,27 +8206,13 @@ using MatchingInstructionWithNoResultFoldingTest =
TEST_P(MatchingInstructionWithNoResultFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_1);
- // Fold the instruction to test.
- Instruction* inst = nullptr;
- Function* func = &*context->module()->begin();
- for (auto& bb : *func) {
- Instruction* terminator = bb.terminator();
- if (terminator->IsReturnOrAbort()) {
- inst = terminator->PreviousNode();
- break;
- }
- }
- assert(inst && "Invalid test. Could not find instruction to fold.");
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
+ // Find the instruction to test.
+ EXPECT_EQ(inst != nullptr, tc.expected_result);
+ if (inst != nullptr) {
Match(tc.test_body, context.get());
}
}
@@ -8157,8 +8552,9 @@ TEST_P(EntryPointFoldingTest, Case) {
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
ASSERT_NE(nullptr, context);
- // Fold the instruction to test.
+ // Find the first entry point. That is the instruction we want to fold.
Instruction* inst = nullptr;
+ ASSERT_FALSE(context->module()->entry_points().empty());
inst = &*context->module()->entry_points().begin();
assert(inst && "Invalid test. Could not find entry point instruction to fold.");
std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
@@ -8251,19 +8647,12 @@ using SPV14FoldingTest =
TEST_P(SPV14FoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_4, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold,SPV_ENV_UNIVERSAL_1_4);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
+ EXPECT_EQ(inst != nullptr, tc.expected_result);
+ if (inst != nullptr) {
Match(tc.test_body, context.get());
}
}
@@ -8364,19 +8753,12 @@ using FloatControlsFoldingTest =
TEST_P(FloatControlsFoldingTest, Case) {
const auto& tc = GetParam();
- // Build module.
- std::unique_ptr<IRContext> context =
- BuildModule(SPV_ENV_UNIVERSAL_1_4, nullptr, tc.test_body,
- SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- ASSERT_NE(nullptr, context);
+ std::unique_ptr<IRContext> context;
+ Instruction* inst;
+ std::tie(context, inst) = FoldInstruction(tc.test_body, tc.id_to_fold, SPV_ENV_UNIVERSAL_1_4);
- // Fold the instruction to test.
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- Instruction* inst = def_use_mgr->GetDef(tc.id_to_fold);
- std::unique_ptr<Instruction> original_inst(inst->Clone(context.get()));
- bool succeeded = context->get_instruction_folder().FoldInstruction(inst);
- EXPECT_EQ(succeeded, tc.expected_result);
- if (succeeded) {
+ EXPECT_EQ(inst != nullptr, tc.expected_result);
+ if (inst != nullptr) {
Match(tc.test_body, context.get());
}
}
@@ -8448,6 +8830,7 @@ std::string ImageOperandsTestBody(const std::string& image_instruction) {
%v3int = OpTypeVector %int 3
%Texture = OpVariable %_ptr_UniformConstant_type_2d_image UniformConstant
%gSampler = OpVariable %_ptr_UniformConstant_type_sampler UniformConstant
+ %110 = OpConstantComposite %v2int %5 %5
%101 = OpConstantComposite %v2int %int_n1 %int_n1
%20 = OpConstantComposite %v2float %float_0 %float_0
%main = OpFunction %void None %22
@@ -8507,7 +8890,12 @@ INSTANTIATE_TEST_SUITE_P(ImageOperandsBitmaskFoldingTest, MatchingInstructionWit
InstructionFoldingCase<bool>(ImageOperandsTestBody(
" OpImageWrite %88 %5 %101 Offset %101 \n"
"; CHECK: OpImageWrite %88 %5 %101 ConstOffset %101 \n")
- , 0 /* No result-id */, true)
+ , 0 /* No result-id */, true),
+ // Test case 8: OpImageFetch with zero constant Offset
+ InstructionFoldingCase<bool>(ImageOperandsTestBody(
+ " %89 = OpImageFetch %10 %88 %101 Lod|Offset %5 %110 \n"
+ "; CHECK: %89 = OpImageFetch %10 %88 %101 Lod %5 \n")
+ , 89, true)
));
} // namespace
diff --git a/third_party/SPIRV-Tools/test/opt/inline_test.cpp b/third_party/SPIRV-Tools/test/opt/inline_test.cpp
index 1e5d9f3b4..bf791811d 100644
--- a/third_party/SPIRV-Tools/test/opt/inline_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inline_test.cpp
@@ -4422,6 +4422,55 @@ OpFunctionEnd
SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
}
+TEST_F(InlineTest, DecorateReturnVariableWithAliasedPointer) {
+ const std::string text = R"(OpCapability Int64
+ OpCapability VariablePointers
+ OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_KHR_variable_pointers"
+ OpExtension "SPV_KHR_physical_storage_buffer"
+ OpMemoryModel PhysicalStorageBuffer64 GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %1 LocalSize 8 8 1
+ OpDecorate %_ptr_PhysicalStorageBuffer__struct_5 ArrayStride 8
+ OpMemberDecorate %_struct_3 0 Offset 0
+ OpMemberDecorate %_struct_3 1 Offset 8
+ OpDecorate %_ptr_PhysicalStorageBuffer_int ArrayStride 4
+ OpMemberDecorate %_struct_5 0 Offset 0
+ OpMemberDecorate %_struct_5 1 Offset 4
+ OpDecorate %6 Aliased
+; CHECK: OpDecorate %22 AliasedPointer
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %int_0 = OpConstant %int 0
+ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer__struct_5 PhysicalStorageBuffer
+ %_struct_3 = OpTypeStruct %int %_ptr_PhysicalStorageBuffer__struct_5
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+ %_struct_5 = OpTypeStruct %int %int
+ %11 = OpTypeFunction %_ptr_PhysicalStorageBuffer_int %_ptr_PhysicalStorageBuffer__struct_5
+%_ptr_PhysicalStorageBuffer__struct_5 = OpTypePointer PhysicalStorageBuffer %_struct_5
+%_ptr_Function__struct_3 = OpTypePointer Function %_struct_3
+ %1 = OpFunction %void None %8
+ %13 = OpLabel
+ %14 = OpVariable %_ptr_Function__struct_3 Function
+ %15 = OpLoad %_struct_3 %14
+ %16 = OpCompositeExtract %_ptr_PhysicalStorageBuffer__struct_5 %15 1
+ %17 = OpFunctionCall %_ptr_PhysicalStorageBuffer_int %18 %16
+ OpReturn
+ OpFunctionEnd
+ %18 = OpFunction %_ptr_PhysicalStorageBuffer_int None %11
+ %6 = OpFunctionParameter %_ptr_PhysicalStorageBuffer__struct_5
+ %19 = OpLabel
+ %20 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %6 %int_0
+ OpReturnValue %20
+ OpFunctionEnd)";
+
+ SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SinglePassRunAndMatch<InlineExhaustivePass>(text, true);
+}
+
// TODO(greg-lunarg): Add tests to verify handling of these cases:
//
// Empty modules
diff --git a/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
index dd4b6f607..08da367fd 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_bindless_check_test.cpp
@@ -27,504 +27,18 @@ namespace {
using InstBindlessTest = PassTest<::testing::Test>;
-static const std::string kOutputDecorations = R"(
-; CHECK: OpDecorate [[output_buffer_type:%inst_bindless_OutputBuffer]] Block
-; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0
-; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4
-; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7
-; CHECK: OpDecorate [[output_buffer_var]] Binding 0
-)";
-
-static const std::string kOutputGlobals = R"(
-; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %uint %_runtimearr_uint
-; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]]
-; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer
-)";
-
-static const std::string kStreamWrite6Begin = R"(
-; CHECK: %inst_bindless_stream_write_6 = OpFunction %void None {{%\w+}}
-; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_5:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_6:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1
-; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_12
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_12
-; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 2
-; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_12
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_23
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_1]]
-)";
+static const std::string kFuncName = "inst_bindless_check_desc";
-static const std::string kStreamWrite6End = R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_2]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_3]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_4]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_5]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_11
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_6]]
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturn
-; CHECK: OpFunctionEnd
+static const std::string kImportDeco = R"(
+;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" +
+ kFuncName + R"(" Import
)";
-// clang-format off
-static const std::string kStreamWrite6Frag = kStreamWrite6Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
-; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite6End;
-
-static const std::string kStreamWrite6Tese = kStreamWrite6Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_2
-; CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord
-; CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite6End;
-
-static const std::string kStreamWrite6Vert = kStreamWrite6Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite6End;
-
-static const std::string kStreamWrite6Compute = kStreamWrite6Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite6End;
-
-static const std::string kStreamWrite6Ray = kStreamWrite6Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite6End;
-// clang-format on
-
-static const std::string kStreamWrite7Begin = R"(
-; CHECK: %inst_bindless_stream_write_7 = OpFunction %void None {{%\w+}}
-; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_5:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_6:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_7:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1
-; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_13
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_13
-; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 2
-; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_13
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_23
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_1]]
-)";
-
-static const std::string kStreamWrite7End = R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_2]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_3]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_4]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_5]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_11
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_6]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_12
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_7]]
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturn
-; CHECK: OpFunctionEnd
-)";
-
-// clang-format off
-static const std::string kStreamWrite7Frag = kStreamWrite7Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
-; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite7End;
-
-static const std::string kStreamWrite7Vert = kStreamWrite7Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite7End;
-// clang-format on
-
-static const std::string kInputDecorations = R"(
-; CHECK: OpDecorate [[desc_set_struct:%inst_bindless_DescriptorSetData]] Block
-; CHECK: OpMemberDecorate [[desc_set_struct]] 0 Offset 0
-; CHECK: OpMemberDecorate [[desc_set_struct]] 1 Offset 4
-; CHECK: OpDecorate [[input_buffer_type:%inst_bindless_InputBuffer]] Block
-; CHECK: OpMemberDecorate [[input_buffer_type]] 0 Offset 0
-; CHECK: OpDecorate [[input_buffer_var:%\w+]] DescriptorSet 7
-; CHECK: OpDecorate [[input_buffer_var]] Binding 1
-)";
-
-static const std::string kInputGlobals = R"(
-; CHECK: [[desc_set_struct]] = OpTypeStruct %uint %_runtimearr_uint
-; CHECK: [[desc_set_ptr:%\w+]] = OpTypePointer PhysicalStorageBuffer [[desc_set_struct]]
-; CHECK: [[desc_set_ptr_array:%\w+]] = OpTypeArray [[desc_set_ptr]] %uint_32
-; CHECK: [[input_buffer_type]] = OpTypeStruct [[desc_set_ptr_array]]
-; CHECK: [[input_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[input_buffer_type]]
-; CHECK: [[input_buffer_var]] = OpVariable [[input_ptr_type]] StorageBuffer
-)";
-
-static const std::string kReadBindingLength = R"(
-; CHECK: %inst_bindless_read_binding_length = OpFunction %uint None {{%\w+}}
-; CHECK: [[bl_desc_set_idx:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[bl_binding_idx:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpUGreaterThanEqual %bool [[bl_desc_set_idx]] %uint_32
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_inst_bindless_DescriptorSetData %inst_bindless_input_buffer %uint_0 [[bl_desc_set_idx]]
-; CHECK: {{%\w+}} = OpLoad %_ptr_PhysicalStorageBuffer_inst_bindless_DescriptorSetData {{%\w+}}
-; CHECK: {{%\w+}} = OpBitcast %v2uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLogicalAnd %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} Aligned 8
-; CHECK: {{%\w+}} = OpUGreaterThanEqual %bool [[bl_binding_idx]] {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%\w+}} %uint_1 [[bl_binding_idx]]
-; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} Aligned 4
-; CHECK: OpReturnValue {{%\w+}}
-; CHECK: OpFunctionEnd
-)";
-
-static const std::string kReadDescInit = R"(
-; CHECK: %inst_bindless_read_desc_init = OpFunction %uint None {{%\w+}}
-; CHECK: [[di_desc_set_idx:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[di_binding_idx:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[di_desc_idx:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpUGreaterThanEqual %bool [[di_desc_set_idx]] %uint_32
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer__ptr_PhysicalStorageBuffer_inst_bindless_DescriptorSetData %inst_bindless_input_buffer %uint_0 [[di_desc_set_idx]]
-; CHECK: {{%\w+}} = OpLoad %_ptr_PhysicalStorageBuffer_inst_bindless_DescriptorSetData {{%\w+}}
-; CHECK: {{%\w+}} = OpBitcast %v2uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLogicalAnd %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%\w+}} %uint_0
-; CHECK: [[di_num_bindings:%\w+]] = OpLoad %uint {{%\w+}} Aligned 8
-; CHECK: {{%\w+}} = OpUGreaterThanEqual %bool [[di_binding_idx]] [[di_num_bindings]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturnValue %uint_0
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%\w+}} %uint_1 {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} Aligned 4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_PhysicalStorageBuffer_uint {{%\w+}} %uint_1 {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %uint {{%\w+}} Aligned 4
-; CHECK: OpReturnValue {{%\w+}}
-; CHECK: OpFunctionEnd
-)";
-
-TEST_F(InstBindlessTest, NoInstrumentConstIndexInbounds) {
- // Texture2D g_tColor[128];
- //
- // SamplerState g_sAniso;
- //
- // struct PS_INPUT
- // {
- // float2 vTextureCoords : TEXCOORD2;
- // };
- //
- // struct PS_OUTPUT
- // {
- // float4 vColor : SV_Target0;
- // };
- //
- // PS_OUTPUT MainPs(PS_INPUT i)
- // {
- // PS_OUTPUT ps_output;
- //
- // ps_output.vColor = g_tColor[ 37 ].Sample(g_sAniso, i.vTextureCoords.xy);
- // return ps_output;
- // }
-
- const std::string before =
- R"(OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
-OpMemoryModel Logical GLSL450
-OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-OpExecutionMode %MainPs OriginUpperLeft
-OpSource HLSL 500
-OpName %MainPs "MainPs"
-OpName %g_tColor "g_tColor"
-OpName %g_sAniso "g_sAniso"
-OpName %i_vTextureCoords "i.vTextureCoords"
-OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
-OpDecorate %g_tColor DescriptorSet 3
-OpDecorate %g_tColor Binding 5
-OpDecorate %g_sAniso DescriptorSet 3
-OpDecorate %i_vTextureCoords Location 0
-OpDecorate %_entryPointOutput_vColor Location 0
-%void = OpTypeVoid
-%8 = OpTypeFunction %void
-%float = OpTypeFloat 32
-%v2float = OpTypeVector %float 2
-%v4float = OpTypeVector %float 4
-%int = OpTypeInt 32 1
-%int_0 = OpConstant %int 0
-%int_37 = OpConstant %int 37
-%15 = OpTypeImage %float 2D 0 0 0 1 Unknown
-%uint = OpTypeInt 32 0
-%uint_128 = OpConstant %uint 128
-%_arr_15_uint_128 = OpTypeArray %15 %uint_128
-%_ptr_UniformConstant__arr_15_uint_128 = OpTypePointer UniformConstant %_arr_15_uint_128
-%g_tColor = OpVariable %_ptr_UniformConstant__arr_15_uint_128 UniformConstant
-%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
-%21 = OpTypeSampler
-%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
-%g_sAniso = OpVariable %_ptr_UniformConstant_21 UniformConstant
-%23 = OpTypeSampledImage %15
-%_ptr_Input_v2float = OpTypePointer Input %v2float
-%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
-%_ptr_Output_v4float = OpTypePointer Output %v4float
-%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-%MainPs = OpFunction %void None %8
-%26 = OpLabel
-%27 = OpLoad %v2float %i_vTextureCoords
-%28 = OpAccessChain %_ptr_UniformConstant_15 %g_tColor %int_37
-%29 = OpLoad %15 %28
-%30 = OpLoad %21 %g_sAniso
-%31 = OpSampledImage %23 %29 %30
-%32 = OpImageSampleImplicitLod %v4float %31 %27
-OpStore %_entryPointOutput_vColor %32
-OpReturn
-OpFunctionEnd
-)";
-
- SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<InstBindlessCheckPass>(
- before, before, true, true, 7u, 23u, false, false, false, false, false);
-}
-
-TEST_F(InstBindlessTest, NoInstrumentNonBindless) {
- // This test verifies that the pass will correctly not instrument vanilla
- // texture sample.
- //
- // Texture2D g_tColor;
- //
- // SamplerState g_sAniso;
- //
- // struct PS_INPUT
- // {
- // float2 vTextureCoords : TEXCOORD2;
- // };
- //
- // struct PS_OUTPUT
- // {
- // float4 vColor : SV_Target0;
- // };
- //
- // PS_OUTPUT MainPs(PS_INPUT i)
- // {
- // PS_OUTPUT ps_output;
- // ps_output.vColor =
- // g_tColor.Sample(g_sAniso, i.vTextureCoords.xy);
- // return ps_output;
- // }
-
- const std::string whole_file =
- R"(OpCapability Shader
-%1 = OpExtInstImport "GLSL.std.450"
-OpMemoryModel Logical GLSL450
-OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-OpExecutionMode %MainPs OriginUpperLeft
-OpSource HLSL 500
-OpName %MainPs "MainPs"
-OpName %g_tColor "g_tColor"
-OpName %g_sAniso "g_sAniso"
-OpName %i_vTextureCoords "i.vTextureCoords"
-OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
-OpDecorate %g_tColor DescriptorSet 6
-OpDecorate %g_tColor Binding 4
-OpDecorate %g_sAniso DescriptorSet 6
-OpDecorate %g_sAniso Binding 4
-OpDecorate %i_vTextureCoords Location 0
-OpDecorate %_entryPointOutput_vColor Location 0
-%void = OpTypeVoid
-%8 = OpTypeFunction %void
-%float = OpTypeFloat 32
-%v2float = OpTypeVector %float 2
-%v4float = OpTypeVector %float 4
-%12 = OpTypeImage %float 2D 0 0 0 1 Unknown
-%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
-%g_tColor = OpVariable %_ptr_UniformConstant_12 UniformConstant
-%14 = OpTypeSampler
-%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
-%g_sAniso = OpVariable %_ptr_UniformConstant_14 UniformConstant
-%16 = OpTypeSampledImage %12
-%_ptr_Input_v2float = OpTypePointer Input %v2float
-%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
-%_ptr_Output_v4float = OpTypePointer Output %v4float
-%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-%MainPs = OpFunction %void None %8
-%19 = OpLabel
-%20 = OpLoad %v2float %i_vTextureCoords
-%21 = OpLoad %12 %g_tColor
-%22 = OpLoad %14 %g_sAniso
-%23 = OpSampledImage %16 %21 %22
-%24 = OpImageSampleImplicitLod %v4float %23 %20
-OpStore %_entryPointOutput_vColor %24
-OpReturn
-OpFunctionEnd
+static const std::string kImportStub = R"(
+;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}}
+;CHECK: OpFunctionEnd
)";
- // SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndCheck<InstBindlessCheckPass>(whole_file, whole_file, true,
- true, 7u, 23u, false, false,
- false, false, false);
-}
-
TEST_F(InstBindlessTest, Simple) {
// Texture2D g_tColor[128];
//
@@ -555,11 +69,11 @@ TEST_F(InstBindlessTest, Simple) {
const std::string entry = R"(
OpCapability Shader
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
)";
@@ -580,10 +94,10 @@ OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
OpDecorate %PerViewConstantBuffer_t Block
OpDecorate %g_sAniso DescriptorSet 0
OpDecorate %i_vTextureCoords Location 0
-OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+OpDecorate %_entryPointOutput_vColor Location 0)"
++ kImportDeco +
+R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
)";
const std::string consts_types_vars = R"(
@@ -613,15 +127,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %10
@@ -635,32 +144,30 @@ OpDecorate %_entryPointOutput_vColor Location 0
%36 = OpSampledImage %26 %34 %35
%37 = OpImageSampleImplicitLod %v4float %36 %30
OpStore %_entryPointOutput_vColor %37
-; CHECK-NOT: %37 = OpImageSampleImplicitLod %v4float %36 %30
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %37
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} %uint_128
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %16 %33
-; CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35
-; CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_56 %uint_0 %uint_3 %uint_0 %32 %uint_128
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpStore %_entryPointOutput_vColor [[phi_result]]
+;CHECK-NOT: %37 = OpImageSampleImplicitLod %v4float %36 %30
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %37
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_57 {{%\w+}} %uint_3 %uint_0 %32 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %16 %33
+;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass, uint32_t, uint32_t, bool, bool>(
- entry + names_annots + consts_types_vars + main_func + output_func, true,
- 7u, 23u, false, false, false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(
+ entry + names_annots + consts_types_vars + kImportStub + main_func, true,
+ 23u);
}
TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
@@ -697,11 +204,11 @@ TEST_F(InstBindlessTest, InstrumentMultipleInstructions) {
// clang-format off
const std::string defs = R"(
OpCapability Shader
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -720,9 +227,8 @@ OpDecorate %PerViewConstantBuffer_t Block
OpDecorate %g_sAniso DescriptorSet 3
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%10 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -750,20 +256,14 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: %bool = OpTypeBool
-; CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
- const std::string main_func =
- R"(%MainPs = OpFunction %void None %10
+ const std::string main_func = R"(
+%MainPs = OpFunction %void None %10
%30 = OpLabel
%31 = OpLoad %v2float %i_vTextureCoords
%32 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
@@ -773,20 +273,24 @@ OpDecorate %_entryPointOutput_vColor Location 0
%36 = OpLoad %25 %g_sAniso
%37 = OpSampledImage %27 %35 %36
%38 = OpImageSampleImplicitLod %v4float %37 %31
-; CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31
-; CHECK: %48 = OpULessThan %bool %33 %uint_128
-; CHECK: OpSelectionMerge %49 None
-; CHECK: OpBranchConditional %48 %50 %51
-; CHECK: %50 = OpLabel
-; CHECK: %52 = OpLoad %17 %34
-; CHECK: %53 = OpSampledImage %27 %52 %36
-; CHECK: %54 = OpImageSampleImplicitLod %v4float %53 %31
-; CHECK: OpBranch %49
-; CHECK: %51 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_58 %uint_0 %uint_3 %uint_4 %33 %uint_128
-; CHECK: OpBranch %49
-; CHECK: %49 = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float %54 %50 [[null_v4float]] %51
+;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_3 %uint_4 %33 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %17 %34
+;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
%39 = OpAccessChain %_ptr_PushConstant_uint %_ %int_1
%40 = OpLoad %uint %39
%41 = OpAccessChain %_ptr_UniformConstant_17 %g_tColor %40
@@ -794,33 +298,35 @@ OpDecorate %_entryPointOutput_vColor Location 0
%43 = OpSampledImage %27 %42 %36
%44 = OpImageSampleImplicitLod %v4float %43 %31
%45 = OpFAdd %v4float %38 %44
-; CHECK-NOT: %44 = OpImageSampleImplicitLod %v4float %43 %31
-; CHECK-NOT: %45 = OpFAdd %v4float %38 %44
-; CHECK: {{%\w+}} = OpULessThan %bool %40 %uint_128
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %17 %41
-; CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
-; CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_64 %uint_0 %uint_3 %uint_4 %40 %uint_128
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %45 = OpFAdd %v4float {{%\w+}} {{%\w+}}
+;CHECK-NOT: %44 = OpImageSampleImplicitLod %v4float %43 %31
+;CHECK-NOT: %45 = OpFAdd %v4float %38 %44
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_66 {{%\w+}} %uint_3 %uint_4 %40 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %17 %41
+;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %45 = OpFAdd %v4float {{%\w+}} {{%\w+}}
OpStore %_entryPointOutput_vColor %45
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentOpImage) {
@@ -832,11 +338,11 @@ TEST_F(InstBindlessTest, InstrumentOpImage) {
const std::string defs = R"(
OpCapability Shader
OpCapability StorageImageReadWithoutFormat
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -852,9 +358,8 @@ OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
OpDecorate %PerViewConstantBuffer_t Block
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -878,17 +383,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: uint_0 = OpConstant %uint 0
-; CHECK: bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %3
@@ -901,32 +399,34 @@ OpDecorate %_entryPointOutput_vColor Location 0
%75 = OpImage %20 %66
%71 = OpImageRead %v4float %75 %53
OpStore %_entryPointOutput_vColor %71
-; CHECK-NOT: %71 = OpImageRead %v4float %75 %53
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %71
-; CHECK: %78 = OpULessThan %bool %64 %uint_128
-; CHECK: OpSelectionMerge %79 None
-; CHECK: OpBranchConditional %78 %80 %81
-; CHECK: %80 = OpLabel
-; CHECK: %82 = OpLoad %39 %65
-; CHECK: %83 = OpImage %20 %82
-; CHECK: %84 = OpImageRead %v4float %83 %53
-; CHECK: OpBranch %79
-; CHECK: %81 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_3 %uint_9 %64 %uint_128
-; CHECK: OpBranch %79
-; CHECK: %79 = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float %84 %80 [[null_v4float]] %81
-; CHECK: OpStore %_entryPointOutput_vColor {{%\w+}}
+;CHECK-NOT: %71 = OpImageRead %v4float %75 %53
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %71
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_9 %64 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %39 %65
+;CHECK: {{%\w+}} = OpImage %20 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %53
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentSampledImage) {
@@ -937,11 +437,11 @@ TEST_F(InstBindlessTest, InstrumentSampledImage) {
// clang-format off
const std::string defs = R"(
OpCapability Shader
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -957,8 +457,8 @@ OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
OpDecorate %PerViewConstantBuffer_t Block
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -982,17 +482,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: uint_0 = OpConstant %uint 0
-; CHECK: bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %3
@@ -1004,31 +497,33 @@ OpDecorate %_entryPointOutput_vColor Location 0
%66 = OpLoad %39 %65
%71 = OpImageSampleImplicitLod %v4float %66 %53
OpStore %_entryPointOutput_vColor %71
-; CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %66 %53
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %71
-; CHECK: %74 = OpULessThan %bool %64 %uint_128
-; CHECK: OpSelectionMerge %75 None
-; CHECK: OpBranchConditional %74 %76 %77
-; CHECK: %76 = OpLabel
-; CHECK: %78 = OpLoad %39 %65
-; CHECK: %79 = OpImageSampleImplicitLod %v4float %78 %53
-; CHECK: OpBranch %75
-; CHECK: %77 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_49 %uint_0 %uint_4 %uint_11 %64 %uint_128
-; CHECK: OpBranch %75
-; CHECK: %75 = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float %79 %76 [[null_v4float]] %77
-; CHECK: OpStore %_entryPointOutput_vColor {{%\w+}}
+;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %66 %53
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %71
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_50 {{%\w+}} %uint_4 %uint_11 %64 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %39 %65
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %53
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentImageWrite) {
@@ -1040,11 +535,11 @@ TEST_F(InstBindlessTest, InstrumentImageWrite) {
const std::string defs = R"(
OpCapability Shader
OpCapability StorageImageWriteWithoutFormat
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -1060,9 +555,8 @@ OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
OpDecorate %PerViewConstantBuffer_t Block
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1087,13 +581,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2int Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %3
@@ -1105,30 +596,33 @@ OpDecorate %_entryPointOutput_vColor Location 0
%66 = OpLoad %20 %65
OpImageWrite %66 %53 %80
OpStore %_entryPointOutput_vColor %80
-; CHECK-NOT: OpImageWrite %66 %53 %80
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %80
-; CHECK: %35 = OpULessThan %bool %30 %uint_128
-; CHECK: OpSelectionMerge %36 None
-; CHECK: OpBranchConditional %35 %37 %38
-; CHECK: %37 = OpLabel
-; CHECK: %39 = OpLoad %16 %31
-; CHECK: OpImageWrite %39 %28 %19
-; CHECK: OpBranch %36
-; CHECK: %38 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_30 %uint_2 %30 %uint_128
-; CHECK: OpBranch %36
-; CHECK: %36 = OpLabel
-; CHECK: OpStore %_entryPointOutput_vColor %19
+;CHECK-NOT: OpImageWrite %66 %53 %80
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %80
+;CHECK: %32 = OpLoad %16 %31
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_30 %uint_2 %30 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %16 %31
+;CHECK: OpImageWrite {{%\w+}} %28 %19
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %_entryPointOutput_vColor %19
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentVertexSimple) {
@@ -1140,7 +634,7 @@ TEST_F(InstBindlessTest, InstrumentVertexSimple) {
const std::string defs = R"(
OpCapability Shader
OpCapability Sampled1D
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %_ %coords2D
@@ -1159,10 +653,9 @@ OpName %foo "foo"
OpMemberName %foo 0 "g_idx"
OpName %__0 ""
OpName %coords2D "coords2D"
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
-; CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
+;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
@@ -1205,16 +698,11 @@ OpDecorate %coords2D Location 0
%v2float = OpTypeVector %float 2
%_ptr_Input_v2float = OpTypePointer Input %v2float
%coords2D = OpVariable %_ptr_Input_v2float Input
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
-; CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
-; CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
+;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
+;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -1232,34 +720,51 @@ OpStore %coords1D %float_1_78900003
%38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37
%40 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %40 %38
-; CHECK-NOT: %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37
-; CHECK-NOT: %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0
-; CHECK-NOT: OpStore %40 %38
-; CHECK: %46 = OpULessThan %bool %37 %uint_128
-; CHECK: OpSelectionMerge %47 None
-; CHECK: OpBranchConditional %46 %48 %49
-; CHECK: %48 = OpLabel
-; CHECK: %50 = OpLoad %25 %38
-; CHECK: %51 = OpImageSampleExplicitLod %v4float %50 %40 Lod %41
-; CHECK: OpBranch %47
-; CHECK: %49 = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %37
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_74 %uint_0 %uint_2 %uint_13 {{%\w+}} %uint_128
-; CHECK: OpBranch %47
-; CHECK: %47 = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float %51 %48 [[null_v4float]] %49
-; CHECK: %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0
-; CHECK: OpStore %43 {{%\w+}}
+;CHECK-NOT: %38 = OpImageSampleExplicitLod %v4float %35 %36 Lod %37
+;CHECK-NOT: %40 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+;CHECK-NOT: OpStore %40 %38
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_70 {{%\w+}} %uint_7 %uint_5 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %int {{%\w+}}
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %int {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_25 %texSampler1D {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %float %coords1D
+;CHECK: {{%\w+}} = OpLoad %float %lod
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_75 {{%\w+}} %uint_2 %uint_13 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %25 %38
+;CHECK: {{%\w+}} = OpImageSampleExplicitLod %v4float {{%\w+}} %40 Lod %41
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: %43 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+;CHECK: OpStore %43 {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Vert;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentTeseSimple) {
@@ -1284,10 +789,11 @@ TEST_F(InstBindlessTest, InstrumentTeseSimple) {
const std::string defs = R"(
OpCapability Tessellation
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint TessellationEvaluation %main "main" %_
-; CHECK: OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord
+;CHECK: OpEntryPoint TessellationEvaluation %main "main" %_ %gl_PrimitiveID %gl_TessCoord
OpExecutionMode %main Triangles
OpExecutionMode %main SpacingEqual
OpExecutionMode %main VertexOrderCw
@@ -1319,10 +825,9 @@ OpMemberDecorate %ufoo 0 Offset 0
OpDecorate %ufoo Block
OpDecorate %uniform_index_buffer DescriptorSet 9
OpDecorate %uniform_index_buffer Binding 2
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
-; CHECK: OpDecorate %gl_TessCoord BuiltIn TessCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_PrimitiveID BuiltIn PrimitiveId
+;CHECK: OpDecorate %gl_TessCoord BuiltIn TessCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1346,53 +851,322 @@ OpDecorate %uniform_index_buffer Binding 2
%_ptr_Uniform_uint = OpTypePointer Uniform %uint
%_ptr_StorageBuffer_v4float = OpTypePointer StorageBuffer %v4float
%_ptr_Output_v4float = OpTypePointer Output %v4float
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
-; CHECK: %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
-; CHECK: %v3float = OpTypeVector %float 3
-; CHECK: %_ptr_Input_v3float = OpTypePointer Input %v3float
-; CHECK: %gl_TessCoord = OpVariable %_ptr_Input_v3float Input
-; CHECK: %v3uint = OpTypeVector %uint 3
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
+;CHECK: %gl_PrimitiveID = OpVariable %_ptr_Input_uint Input
+;CHECK: %v3float = OpTypeVector %float 3
+;CHECK: %_ptr_Input_v3float = OpTypePointer Input %v3float
+;CHECK: %gl_TessCoord = OpVariable %_ptr_Input_v3float Input
+;CHECK: %v3uint = OpTypeVector %uint 3
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
- const std::string main_func = R"(
+ const std::string main_func =
+ R"(
%main = OpFunction %void None %3
%5 = OpLabel
%25 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0
%26 = OpLoad %uint %25
%28 = OpAccessChain %_ptr_StorageBuffer_v4float %adds %26 %int_0
%29 = OpLoad %v4float %28
-; CHECK-NOT: %29 = OpLoad %v4float %28
-; CHECK: %34 = OpULessThan %bool %28 %uint_11
-; CHECK: OpSelectionMerge %35 None
-; CHECK: OpBranchConditional %34 %36 %37
-; CHECK: %36 = OpLabel
-; CHECK: %38 = OpLoad %v4float %29
-; CHECK: OpBranch %35
-; CHECK: %37 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_63 %uint_0 %uint_9 %uint_1 %28 %uint_11
-; CHECK: OpBranch %35
-; CHECK: %35 = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float %38 %36 [[null_v4float]] %37
+;CHECK-NOT: %29 = OpLoad %v4float %28
+;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID
+;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord
+;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_62 {{%\w+}} %uint_9 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %27
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
%31 = OpAccessChain %_ptr_Output_v4float %_ %int_0
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: OpStore %31 {{%\w+}}
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID
+;CHECK: {{%\w+}} = OpLoad %v3float %gl_TessCoord
+;CHECK: {{%\w+}} = OpBitcast %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_2 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_64 {{%\w+}} %uint_9 %uint_1 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %v4float %29
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: %31 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+;CHECK: OpStore %31 [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Tese;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + output_func,
- true, 7u, 23u, false, false,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
+}
+
+TEST_F(InstBindlessTest, InstrumentTesc) {
+ // This test verifies that the pass will correctly instrument tessellation
+ // control shader
+ //
+ // clang-format off
+ //
+ // #version 450
+ // layout(vertices = 3) out;
+ // layout(set = 0, binding = 0) uniform texture1D _77;
+ // layout(set = 0, binding = 1) uniform sampler _78;
+
+ // layout(location = 1) flat in int _3[];
+ // layout(location = 0) out vec4 _5[3];
+
+ // void main()
+ // {
+ // float param;
+ // if (_3[gl_InvocationID] == 0)
+ // {
+ // param = 0.0234375;
+ // }
+ // else
+ // {
+ // param = 1.0156199932098388671875;
+ // }
+ // _5[gl_InvocationID] = textureLod(sampler1D(_77, _78), param, 0.0);
+ // vec4 _203;
+ // if (gl_InvocationID == 0)
+ // {
+ // _203 = gl_in[0].gl_Position;
+ // }
+ // else
+ // {
+ // _203 = gl_in[2].gl_Position;
+ // }
+ // gl_out[gl_InvocationID].gl_Position = _203;
+ // gl_TessLevelInner[0] = 2.7999999523162841796875;
+ // gl_TessLevelInner[1] = 2.7999999523162841796875;
+ // gl_TessLevelOuter[0] = 2.7999999523162841796875;
+ // gl_TessLevelOuter[1] = 2.7999999523162841796875;
+ // gl_TessLevelOuter[2] = 2.7999999523162841796875;
+ // gl_TessLevelOuter[3] = 2.7999999523162841796875;
+ // }
+ //
+ // clang-format on
+ //
+ //
+
+ // clang-format off
+ const std::string defs = R"(
+OpCapability Tessellation
+OpCapability Sampled1D
+;CHECK: OpCapability Linkage
+;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpExtension "SPV_KHR_physical_storage_buffer"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+;CHECK: OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter
+;CHECK: OpEntryPoint TessellationControl %main "main" %_3 %gl_InvocationID %_5 %gl_in %gl_out %gl_TessLevelInner %gl_TessLevelOuter %gl_PrimitiveID
+OpExecutionMode %main OutputVertices 3
+OpSource GLSL 450
+OpName %main "main"
+OpName %_3 "_3"
+OpName %gl_InvocationID "gl_InvocationID"
+OpName %param "param"
+OpName %_5 "_5"
+OpName %_77 "_77"
+OpName %_78 "_78"
+OpName %_203 "_203"
+OpName %gl_PerVertex "gl_PerVertex"
+OpMemberName %gl_PerVertex 0 "gl_Position"
+OpMemberName %gl_PerVertex 1 "gl_PointSize"
+OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+OpMemberName %gl_PerVertex 3 "gl_CullDistance"
+OpName %gl_in "gl_in"
+OpName %gl_PerVertex_0 "gl_PerVertex"
+OpMemberName %gl_PerVertex_0 0 "gl_Position"
+OpMemberName %gl_PerVertex_0 1 "gl_PointSize"
+OpMemberName %gl_PerVertex_0 2 "gl_ClipDistance"
+OpMemberName %gl_PerVertex_0 3 "gl_CullDistance"
+OpName %gl_out "gl_out"
+OpName %gl_TessLevelInner "gl_TessLevelInner"
+OpName %gl_TessLevelOuter "gl_TessLevelOuter"
+OpDecorate %_3 Flat
+OpDecorate %_3 Location 1
+OpDecorate %gl_InvocationID BuiltIn InvocationId
+OpDecorate %_5 Location 0
+OpDecorate %_77 DescriptorSet 0
+OpDecorate %_77 Binding 0
+OpDecorate %_78 DescriptorSet 0
+OpDecorate %_78 Binding 1
+OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+OpDecorate %gl_PerVertex Block
+OpMemberDecorate %gl_PerVertex_0 0 BuiltIn Position
+OpMemberDecorate %gl_PerVertex_0 1 BuiltIn PointSize
+OpMemberDecorate %gl_PerVertex_0 2 BuiltIn ClipDistance
+OpMemberDecorate %gl_PerVertex_0 3 BuiltIn CullDistance
+OpDecorate %gl_PerVertex_0 Block
+OpDecorate %gl_TessLevelInner Patch
+OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner
+OpDecorate %gl_TessLevelOuter Patch
+OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%uint = OpTypeInt 32 0
+%uint_32 = OpConstant %uint 32
+%_arr_int_uint_32 = OpTypeArray %int %uint_32
+%_ptr_Input__arr_int_uint_32 = OpTypePointer Input %_arr_int_uint_32
+%_3 = OpVariable %_ptr_Input__arr_int_uint_32 Input
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_InvocationID = OpVariable %_ptr_Input_int Input
+%int_0 = OpConstant %int 0
+%bool = OpTypeBool
+%float = OpTypeFloat 32
+%_ptr_Function_float = OpTypePointer Function %float
+%float_0_0234375 = OpConstant %float 0.0234375
+%float_1_01561999 = OpConstant %float 1.01561999
+%v4float = OpTypeVector %float 4
+%uint_3 = OpConstant %uint 3
+%_arr_v4float_uint_3 = OpTypeArray %v4float %uint_3
+%_ptr_Output__arr_v4float_uint_3 = OpTypePointer Output %_arr_v4float_uint_3
+%_5 = OpVariable %_ptr_Output__arr_v4float_uint_3 Output
+%34 = OpTypeImage %float 1D 0 0 0 1 Unknown
+%_ptr_UniformConstant_34 = OpTypePointer UniformConstant %34
+%_77 = OpVariable %_ptr_UniformConstant_34 UniformConstant
+%38 = OpTypeSampler
+%_ptr_UniformConstant_38 = OpTypePointer UniformConstant %38
+%_78 = OpVariable %_ptr_UniformConstant_38 UniformConstant
+%42 = OpTypeSampledImage %34
+%float_0 = OpConstant %float 0
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+%uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_arr_gl_PerVertex_uint_32 = OpTypeArray %gl_PerVertex %uint_32
+%_ptr_Input__arr_gl_PerVertex_uint_32 = OpTypePointer Input %_arr_gl_PerVertex_uint_32
+%gl_in = OpVariable %_ptr_Input__arr_gl_PerVertex_uint_32 Input
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%int_2 = OpConstant %int 2
+%gl_PerVertex_0 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_arr_gl_PerVertex_0_uint_3 = OpTypeArray %gl_PerVertex_0 %uint_3
+%_ptr_Output__arr_gl_PerVertex_0_uint_3 = OpTypePointer Output %_arr_gl_PerVertex_0_uint_3
+%gl_out = OpVariable %_ptr_Output__arr_gl_PerVertex_0_uint_3 Output
+%uint_2 = OpConstant %uint 2
+%_arr_float_uint_2 = OpTypeArray %float %uint_2
+%_ptr_Output__arr_float_uint_2 = OpTypePointer Output %_arr_float_uint_2
+%gl_TessLevelInner = OpVariable %_ptr_Output__arr_float_uint_2 Output
+%float_2_79999995 = OpConstant %float 2.79999995
+%_ptr_Output_float = OpTypePointer Output %float
+%int_1 = OpConstant %int 1
+%uint_4 = OpConstant %uint 4
+%_arr_float_uint_4 = OpTypeArray %float %uint_4
+%_ptr_Output__arr_float_uint_4 = OpTypePointer Output %_arr_float_uint_4
+%gl_TessLevelOuter = OpVariable %_ptr_Output__arr_float_uint_4 Output
+%int_3 = OpConstant %int 3
+)";
+
+ const std::string main_func =
+ R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+%param = OpVariable %_ptr_Function_float Function
+%_203 = OpVariable %_ptr_Function_v4float Function
+%14 = OpLoad %int %gl_InvocationID
+%15 = OpAccessChain %_ptr_Input_int %_3 %14
+%16 = OpLoad %int %15
+%19 = OpIEqual %bool %16 %int_0
+OpSelectionMerge %21 None
+OpBranchConditional %19 %20 %26
+%20 = OpLabel
+;CHECK-NOT: %15 = OpAccessChain %_ptr_Input_int %_3 %14
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_Input_int %_3 {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %int {{%\w+}}
+;CHECK: {{%\w+}} = OpIEqual %bool {{%\w+}} %int_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+OpStore %param %float_0_0234375
+OpBranch %21
+%26 = OpLabel
+OpStore %param %float_1_01561999
+OpBranch %21
+%21 = OpLabel
+%33 = OpLoad %int %gl_InvocationID
+%37 = OpLoad %34 %_77
+%41 = OpLoad %38 %_78
+%43 = OpSampledImage %42 %37 %41
+%44 = OpLoad %float %param
+;CHECK: {{%\w+}} = OpLoad %int %gl_InvocationID
+;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %uint %gl_PrimitiveID
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_1 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %inst_bindless_check_desc %uint_23 %uint_129 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+%46 = OpImageSampleExplicitLod %v4float %43 %44 Lod %float_0
+%48 = OpAccessChain %_ptr_Output_v4float %_5 %33
+OpStore %48 %46
+;CHECK-NOT: %48 = OpAccessChain %_ptr_Output_v4float %_5 %33
+;CHECK-NOT: OpStore %48 %46
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: [[access_chain:%\w+]] = OpAccessChain %_ptr_Output_v4float %_5 {{%\w+}}
+;CHECK: OpStore [[access_chain]] [[phi_result]]
+%49 = OpLoad %int %gl_InvocationID
+%50 = OpIEqual %bool %49 %int_0
+OpSelectionMerge %52 None
+OpBranchConditional %50 %51 %64
+%51 = OpLabel
+%62 = OpAccessChain %_ptr_Input_v4float %gl_in %int_0 %int_0
+%63 = OpLoad %v4float %62
+OpStore %_203 %63
+OpBranch %52
+%64 = OpLabel
+%66 = OpAccessChain %_ptr_Input_v4float %gl_in %int_2 %int_0
+%67 = OpLoad %v4float %66
+OpStore %_203 %67
+OpBranch %52
+%52 = OpLabel
+%72 = OpLoad %int %gl_InvocationID
+%73 = OpLoad %v4float %_203
+%74 = OpAccessChain %_ptr_Output_v4float %gl_out %72 %int_0
+OpStore %74 %73
+%81 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_0
+OpStore %81 %float_2_79999995
+%83 = OpAccessChain %_ptr_Output_float %gl_TessLevelInner %int_1
+OpStore %83 %float_2_79999995
+%88 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_0
+OpStore %88 %float_2_79999995
+%89 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_1
+OpStore %89 %float_2_79999995
+%90 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_2
+OpStore %90 %float_2_79999995
+%92 = OpAccessChain %_ptr_Output_float %gl_TessLevelOuter %int_3
+OpStore %92 %float_2_79999995
+OpReturn
+OpFunctionEnd
+)";
+ // clang-format on
+
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, MultipleDebugFunctions) {
@@ -1402,11 +1176,11 @@ TEST_F(InstBindlessTest, MultipleDebugFunctions) {
// clang-format off
const std::string defs = R"(
OpCapability Shader
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%2 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
%1 = OpString "foo5.frag"
OpSource HLSL 500 %1
@@ -1435,9 +1209,8 @@ OpDecorate %g_sAniso DescriptorSet 1
OpDecorate %g_sAniso Binding 3
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%4 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1471,16 +1244,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-; CHECK: %bool = OpTypeBool
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string func1 = R"(
%MainPs = OpFunction %void None %4
@@ -1515,41 +1282,43 @@ OpLine %1 24 0
%43 = OpAccessChain %_ptr_Function_v2float %i %int_0
%44 = OpLoad %v2float %43
%45 = OpImageSampleImplicitLod %v4float %41 %44
-; CHECK-NOT: %45 = OpImageSampleImplicitLod %v4float %41 %44
-; CHECK: OpNoLine
-; CHECK: %62 = OpULessThan %bool %50 %uint_128
-; CHECK: OpSelectionMerge %63 None
-; CHECK: OpBranchConditional %62 %64 %65
-; CHECK: %64 = OpLabel
-; CHECK: %66 = OpLoad %27 %51
-; CHECK: %67 = OpSampledImage %37 %66 %53
-; CHECK: OpLine %5 24 0
-; CHECK: %68 = OpImageSampleImplicitLod %v4float %67 %56
-; CHECK: OpNoLine
-; CHECK: OpBranch %63
-; CHECK: %65 = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_109 %uint_0 %uint_1 %uint_2 %50 %uint_128
-; CHECK: OpBranch %63
-; CHECK: %63 = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %v4float %68 %64 [[null_v4float]] %65
-; CHECK: OpLine %5 24 0
+;CHECK-NOT: %45 = OpImageSampleImplicitLod %v4float %41 %44
+;CHECK: {{%\w+}} = OpLoad %v2float {{%\w+}}
+;CHECK: OpNoLine
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_128 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %27 {{%\w+}}
+;CHECK: {{%\w+}} = OpSampledImage %37 {{%\w+}} {{%\w+}}
+;CHECK: OpLine %5 24 0
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} {{%\w+}}
+;CHECK: OpNoLine
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
%47 = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
OpStore %47 %45
-; CHECK-NOT: OpStore %47 %45
-; CHECK: [[store_loc:%\w+]] = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
-; CHECK: OpStore [[store_loc]] [[phi_result]]
+;CHECK-NOT: OpStore %47 %45
+;CHECK: [[store_loc:%\w+]] = OpAccessChain %_ptr_Function_v4float %ps_output %int_0
+;CHECK: OpStore [[store_loc]] [[phi_result]]
OpLine %1 25 0
%48 = OpLoad %PS_OUTPUT %ps_output
OpReturnValue %48
OpFunctionEnd
)";
-
- const std::string output_func = kStreamWrite6Frag;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<InstBindlessCheckPass>(
- defs + func1 + func2 + output_func, true, 7u, 23u, false, false, false,
- false, false);
+ defs + kImportStub + func1 + func2, true, 23u);
}
TEST_F(InstBindlessTest, RuntimeArray) {
@@ -1561,12 +1330,12 @@ TEST_F(InstBindlessTest, RuntimeArray) {
const std::string defs = R"(
OpCapability Shader
OpCapability RuntimeDescriptorArray
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -1585,9 +1354,8 @@ OpDecorate %g_sAniso DescriptorSet 1
OpDecorate %g_sAniso Binding 3
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1614,13 +1382,10 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %3
@@ -1634,47 +1399,34 @@ OpDecorate %_entryPointOutput_vColor Location 0
%68 = OpSampledImage %39 %66 %67
%71 = OpImageSampleImplicitLod %v4float %68 %53
OpStore %_entryPointOutput_vColor %71
-; CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %68 %53
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %71
-; CHECK: [[length_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_1 %uint_2
-; CHECK: {{%\w+}} = OpULessThan %bool %32 [[length_result]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %16 %33
-; CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35
-; CHECK: [[state_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %32
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 [[state_result]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %16 %33
-; CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35
-; CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_59 %uint_1 %uint_1 %uint_2 %32 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_59 %uint_0 %uint_1 %uint_2 %32 {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %v4float [[phi_result_1]] {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpStore %_entryPointOutput_vColor [[phi_result_2]]
+;CHECK-NOT: %71 = OpImageSampleImplicitLod %v4float %68 %53
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %71
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_60 {{%\w+}} %uint_1 %uint_2 %32 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %16 %33
+;CHECK: {{%\w+}} = OpSampledImage %26 {{%\w+}} %35
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result_1:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor [[phi_result_1]]
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) {
@@ -1688,11 +1440,11 @@ TEST_F(InstBindlessTest, InstrumentInitCheckOnScalarDescriptor) {
// clang-format off
const std::string defs = R"(
OpCapability Shader
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpCapability Linkage
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor
-; CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
OpExecutionMode %MainPs OriginUpperLeft
OpSource HLSL 500
OpName %MainPs "MainPs"
@@ -1706,9 +1458,8 @@ OpDecorate %g_sAniso DescriptorSet 1
OpDecorate %g_sAniso Binding 2
OpDecorate %i_vTextureCoords Location 0
OpDecorate %_entryPointOutput_vColor Location 0
-; check: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; check: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1725,13 +1476,8 @@ OpDecorate %_entryPointOutput_vColor Location 0
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%MainPs = OpFunction %void None %8
@@ -1742,46 +1488,38 @@ OpDecorate %_entryPointOutput_vColor Location 0
%23 = OpSampledImage %16 %21 %22
%24 = OpImageSampleImplicitLod %v4float %23 %20
OpStore %_entryPointOutput_vColor %24
-; CHECK-NOT: %24 = OpImageSampleImplicitLod %v4float %23 %20
-; CHECK-NOT: OpStore %_entryPointOutput_vColor %24
-; CHECK: [[state_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 [[state_result]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %12 %g_tColor
-; CHECK: {{%\w+}} = OpSampledImage %16 {{%\w+}} %22
-; CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_39 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpStore %_entryPointOutput_vColor [[phi_result]]
+;CHECK-NOT: %24 = OpImageSampleImplicitLod %v4float %23 %20
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %24
+;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_40 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %12 %g_tColor
+;CHECK: {{%\w+}} = OpSampledImage %16 {{%\w+}} %22
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs = kReadDescInit + kStreamWrite6Frag;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, SPV14AddToEntryPoint) {
const std::string text = R"(
-; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
-; CHECK: OpDecorate [[v1]] DescriptorSet 7
-; CHECK: OpDecorate [[v2]] DescriptorSet 7
-; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer
-; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer
OpCapability Shader
OpExtension "SPV_EXT_descriptor_indexing"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var
+;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord
OpExecutionMode %foo OriginUpperLeft
OpDecorate %image_var DescriptorSet 4
OpDecorate %image_var Binding 1
@@ -1824,23 +1562,19 @@ OpFunctionEnd
)";
SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, SPV14AddToEntryPoints) {
const std::string text = R"(
-; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
-; CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]]
-; CHECK: OpDecorate [[v1]] DescriptorSet 7
-; CHECK: OpDecorate [[v2]] DescriptorSet 7
-; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer
-; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer
OpCapability Shader
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var
+;CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord
OpEntryPoint Fragment %foo "bar" %gid %image_var %sampler_var
+;CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} %gl_FragCoord
OpExecutionMode %foo OriginUpperLeft
OpDecorate %image_var DescriptorSet 3
OpDecorate %image_var Binding 2
@@ -1883,8 +1617,7 @@ OpFunctionEnd
)";
SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
- false, false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedUBOArray) {
@@ -1907,12 +1640,12 @@ OpCapability Shader
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability UniformBufferArrayNonUniformIndexing
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %b %nu_ii
-; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -1932,12 +1665,10 @@ OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate {{%\w+}} NonUniform
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-; CHECK: OpDecorate {{%\w+}} NonUniform
+;CHECK: OpDecorate {{%\w+}} NonUniform
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+;CHECK: OpDecorate {{%\w+}} NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -1952,14 +1683,12 @@ OpDecorate %20 NonUniform
%nu_ii = OpVariable %_ptr_Input_int Input
%int_0 = OpConstant %int 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %v4float = OpTypeVector %float 4
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_float:%\w+]] = OpConstantNull %float
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4float = OpTypeVector %float 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_float:%\w+]] = OpConstantNull %float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -1968,46 +1697,33 @@ OpDecorate %20 NonUniform
%19 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %16 %int_0
%20 = OpLoad %float %19
OpStore %b %20
-; CHECK-NOT: %20 = OpLoad %float %19
-; CHECK-NOT: OpStore %b %20
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_6 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool %7 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_6 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %float %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_1 %uint_6 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[bitcast_result:%\w+]] = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_0 %uint_6 %uint_3 [[bitcast_result]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %float [[phi_result_1]] {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpStore %b [[phi_result_2]]
+;CHECK-NOT: %20 = OpLoad %float %19
+;CHECK-NOT: OpStore %b %20
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %7
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_6 %uint_3 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %float %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %b [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArrayDeprecated) {
@@ -2030,12 +1746,12 @@ OpCapability Shader
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %b %nu_ii
-; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2055,9 +1771,8 @@ OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2072,16 +1787,13 @@ OpDecorate %20 NonUniform
%nu_ii = OpVariable %_ptr_Input_int Input
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-; CHECK: %uint = OpTypeInt 32 0
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %v4float = OpTypeVector %float 4
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_float:%\w+]] = OpConstantNull %float
+;CHECK: %uint = OpTypeInt 32 0
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4float = OpTypeVector %float 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_float:%\w+]] = OpConstantNull %float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2090,46 +1802,33 @@ OpDecorate %20 NonUniform
%19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0
%20 = OpLoad %float %19
OpStore %b %20
-; CHECK-NOT: %20 = OpLoad %float %19
-; CHECK-NOT: OpStore %b %20
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_7 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool %7 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[bitcast_result_1:%\w+]] = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_7 %uint_3 [[bitcast_result_1]]
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %float %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_1 %uint_7 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[bitcast_result_2:%\w+]] = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_0 %uint_7 %uint_3 [[bitcast_result_2]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %float [[phi_result_1]] {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpStore %b [[phi_result_2]]
+;CHECK-NOT: %20 = OpLoad %float %19
+;CHECK-NOT: OpStore %b %20
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %7
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_7 %uint_3 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %float %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %b [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsAndInitLoadUnsizedSSBOArray) {
@@ -2141,12 +1840,12 @@ OpCapability Shader
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %b %nu_ii
-; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2166,12 +1865,10 @@ OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniform
OpDecorate %16 NonUniform
OpDecorate %20 NonUniform
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate {{%\w+}} NonUniform
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-; CHECK: OpDecorate {{%\w+}} NonUniform
+;CHECK: OpDecorate {{%\w+}} NonUniform
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+;CHECK: OpDecorate {{%\w+}} NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2186,14 +1883,12 @@ OpDecorate %20 NonUniform
%nu_ii = OpVariable %_ptr_Input_int Input
%int_0 = OpConstant %int 0
%_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %v4float = OpTypeVector %float 4
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_float:%\w+]] = OpConstantNull %float
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4float = OpTypeVector %float 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_float:%\w+]] = OpConstantNull %float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2202,46 +1897,33 @@ OpDecorate %20 NonUniform
%19 = OpAccessChain %_ptr_StorageBuffer_float %storageBuffer %16 %int_0
%20 = OpLoad %float %19
OpStore %b %20
-; CHECK-NOT: %20 = OpLoad %float %19
-; CHECK-NOT: OpStore %b %20
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_0 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool %7 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %float %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_1 %uint_0 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[bitcast_result:%\w+]] = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_0 %uint_0 %uint_3 [[bitcast_result]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %float [[phi_result_1]] {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpStore %b [[phi_result_2]]
+;CHECK-NOT: %20 = OpLoad %float %19
+;CHECK-NOT: OpStore %b %20
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %7
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_3 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %float %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %b {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstInitLoadUBOScalar) {
@@ -2259,12 +1941,12 @@ TEST_F(InstBindlessTest, InstInitLoadUBOScalar) {
// clang-format off
const std::string defs = R"(
OpCapability Shader
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %b
-; CHECK: OpEntryPoint Fragment %main "main" %b %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %b %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2278,9 +1960,8 @@ OpMemberDecorate %uname 0 Offset 0
OpDecorate %uname Block
OpDecorate %uniformBuffer DescriptorSet 7
OpDecorate %uniformBuffer Binding 3
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2292,18 +1973,15 @@ OpDecorate %uniformBuffer Binding 3
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %int = OpTypeInt 32 1
-; CHECK: %_ptr_Uniform_float = OpTypePointer Uniform %float
-; CHECK: %uint = OpTypeInt 32 0
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %v4float = OpTypeVector %float 4
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_float:%\w+]] = OpConstantNull %float
+;CHECK: %int = OpTypeInt 32 1
+;CHECK: %_ptr_Uniform_float = OpTypePointer Uniform %float
+;CHECK: %uint = OpTypeInt 32 0
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4float = OpTypeVector %float 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_float:%\w+]] = OpConstantNull %float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2311,31 +1989,32 @@ OpDecorate %uniformBuffer Binding 3
%15 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %int_0
%16 = OpLoad %float %15
OpStore %b %16
-; CHECK-NOT: %16 = OpLoad %float %15
-; CHECK-NOT: OpStore %b %16
-; CHECK: [[check_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_7 %uint_3 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 [[check_result]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %float %15
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_32 %uint_1 %uint_7 %uint_3 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpStore %b [[phi_result]]
+;CHECK-NOT: %16 = OpLoad %float %15
+;CHECK-NOT: OpStore %b %16
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_7 %uint_3 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %float %15
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %b [[phi_result]]
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs = kReadDescInit + kStreamWrite6Frag;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) {
@@ -2357,12 +2036,12 @@ TEST_F(InstBindlessTest, InstBoundsInitStoreUnsizedSSBOArray) {
OpCapability ShaderNonUniform
OpCapability RuntimeDescriptorArray
OpCapability StorageBufferArrayNonUniformIndexing
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %nu_ii %b
-; CHECK: OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %nu_ii %b %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2381,9 +2060,8 @@ OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniform
OpDecorate %14 NonUniform
OpDecorate %b Location 1
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2398,11 +2076,9 @@ OpDecorate %b Location 1
%_ptr_Input_float = OpTypePointer Input %float
%b = OpVariable %_ptr_Input_float Input
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2411,42 +2087,30 @@ OpDecorate %b Location 1
%18 = OpLoad %float %b
%20 = OpAccessChain %_ptr_Uniform_float %storageBuffer %14 %int_0
OpStore %20 %18
-; CHECK-NOT: OpStore %20 %18
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_5 %uint_4
-; CHECK: {{%\w+}} = OpULessThan %bool %7 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_5 %uint_4 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %20 %19
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_1 %uint_5 %uint_4 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_45 %uint_0 %uint_5 %uint_4 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: OpStore %20 %18
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %7
+;CHECK: [[check_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_5 %uint_4 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional [[check_result]] {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %20 %19
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) {
@@ -2468,12 +2132,12 @@ TEST_F(InstBindlessTest, InstBoundsInitLoadSizedUBOArray) {
OpCapability Shader
OpCapability ShaderNonUniform
OpCapability UniformBufferArrayNonUniformIndexing
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %b %nu_ii
-; CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %b %nu_ii %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2493,11 +2157,9 @@ OpDecorate %nu_ii Location 0
OpDecorate %nu_ii NonUniform
OpDecorate %18 NonUniform
OpDecorate %22 NonUniform
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate [[load_result:%\w+]] NonUniform
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+;CHECK: OpDecorate [[load_result:%\w+]] NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
@@ -2514,14 +2176,10 @@ OpDecorate %22 NonUniform
%nu_ii = OpVariable %_ptr_Input_int Input
%int_0 = OpConstant %int 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kOutputGlobals + R"(
-; CHECK: %v4float = OpTypeVector %float 4
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
-; CHECK: [[null_float:%\w+]] = OpConstantNull %float
-)" + kInputGlobals;
- // clang-format on
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_float:%\w+]] = OpConstantNull %float
+)";
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2530,44 +2188,33 @@ OpDecorate %22 NonUniform
%21 = OpAccessChain %_ptr_Uniform_float %uniformBuffer %18 %int_0
%22 = OpLoad %float %21
OpStore %b %22
-; CHECK-NOT: %22 = OpLoad %float %21
-; CHECK-NOT: OpStore %b %22
-; CHECK: {{%\w+}} = OpULessThan %bool %7 %uint_128
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[load_result]] = OpLoad %float %22
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_46 %uint_1 %uint_1 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %float {{%\w+}} {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpBitcast %uint %7
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_46 %uint_0 %uint_1 %uint_3 {{%\w+}} %uint_128
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %float [[phi_result_1]] {{%\w+}} [[null_float]] {{%\w+}}
-; CHECK: OpStore %b [[phi_result_2]]
+;CHECK-NOT: %22 = OpLoad %float %21
+;CHECK-NOT: OpStore %b %22
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %7
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} %uint_1 %uint_3 {{%\w+}} {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %float %22
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %b {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs = kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -2593,12 +2240,12 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability Shader
OpCapability RuntimeDescriptorArray
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %main "main"
-; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -2616,9 +2263,8 @@ OpDecorate %sbo Binding 0
OpDecorate %images DescriptorSet 2
OpDecorate %images Binding 1
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -2640,14 +2286,12 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: %v3uint = OpTypeVector %uint 3
-; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint
-; CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: %v3uint = OpTypeVector %uint 3
+;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2660,70 +2304,64 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_0 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_47 %uint_1 %uint_2 %uint_0 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_1:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_2 %uint_1
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_1 [[phi_result_1]]
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_50 %uint_1 %uint_2 %uint_1 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result_2:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_50 %uint_0 %uint_2 %uint_1 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float [[phi_result_2]] {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: [[desc_state_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_0 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 [[desc_state_result]]
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_53 %uint_1 %uint_2 %uint_0 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_48 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_51 {{%\w+}} %uint_2 %uint_1 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_54 {{%\w+}} %uint_2 %uint_0 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 {{%\w+}}
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Compute + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -2748,13 +2386,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint RayGenerationNV %main "main"
-; CHECK: OpEntryPoint RayGenerationNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint RayGenerationNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -2772,9 +2410,8 @@ OpDecorate %sbo Binding 1
OpDecorate %images DescriptorSet 3
OpDecorate %images Binding 5
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -2796,11 +2433,9 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2813,70 +2448,64 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_3 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_3 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_3 %uint_5
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_3 %uint_5 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_3 %uint_5 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_3 %uint_5 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_3 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_3 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_5 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5313 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_3 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore {{%\w+}} {{%\w+}}
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -2901,13 +2530,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint IntersectionNV %main "main"
-; CHECK: OpEntryPoint IntersectionNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint IntersectionNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -2925,9 +2554,8 @@ OpDecorate %sbo Binding 1
OpDecorate %images DescriptorSet 5
OpDecorate %images Binding 3
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -2949,12 +2577,10 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -2967,70 +2593,63 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_5 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_5 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_5 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_5 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_5 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_5 %uint_3 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_5 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_5 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_5 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: {{%\w+}} = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5314 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_5 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 {{%\w+}}
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -3055,13 +2674,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint AnyHitNV %main "main"
-; CHECK: OpEntryPoint AnyHitNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint AnyHitNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -3079,9 +2698,8 @@ OpDecorate %sbo Binding 1
OpDecorate %images DescriptorSet 2
OpDecorate %images Binding 3
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -3103,12 +2721,10 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -3121,70 +2737,70 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_2 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_2 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_2 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_2 %uint_3 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_2 %uint_1 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_2 %uint_1 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: %20 = OpLoad %uint %19
+;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
+;CHECK-NOT: %23 = OpLoad %13 %22
+;CHECK-NOT: %27 = OpImageRead %v4float %23 %25
+;CHECK-NOT: %29 = OpCompositeExtract %float %27 0
+;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]]
+;CHECK: %28 = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_2 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5315 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_2 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -3209,13 +2825,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint ClosestHitNV %main "main"
-; CHECK: OpEntryPoint ClosestHitNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint ClosestHitNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -3233,9 +2849,8 @@ OpDecorate %sbo Binding 2
OpDecorate %images DescriptorSet 1
OpDecorate %images Binding 3
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -3257,12 +2872,10 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -3275,70 +2888,70 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]]
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_1 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_1 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_1 %uint_3 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_1 %uint_2
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: %20 = OpLoad %uint %19
+;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
+;CHECK-NOT: %23 = OpLoad %13 %22
+;CHECK-NOT: %27 = OpImageRead %v4float %23 %25
+;CHECK-NOT: %29 = OpCompositeExtract %float %27 0
+;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]]
+;CHECK: %28 = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5316 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -3363,13 +2976,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint MissNV %main "main"
-; CHECK: OpEntryPoint MissNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint MissNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -3387,9 +3000,8 @@ OpDecorate %sbo Binding 2
OpDecorate %images DescriptorSet 1
OpDecorate %images Binding 3
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -3411,12 +3023,10 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[launch_id]] = OpVariable %_ptr_Input_v3uint Input
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -3429,70 +3039,67 @@ OpDecorate %images NonWritable
%29 = OpCompositeExtract %float %27 0
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]]
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_1 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_1 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_1 %uint_3 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: %20 = OpLoad %uint %19
+;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
+;CHECK-NOT: %27 = OpImageRead %v4float %23 %25
+;CHECK-NOT: %29 = OpCompositeExtract %float %27 0
+;CHECK-NOT OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images [[phi_result]]
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5317 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest,
@@ -3517,13 +3124,13 @@ TEST_F(InstBindlessTest,
const std::string defs = R"(
OpCapability RuntimeDescriptorArray
OpCapability RayTracingNV
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
OpExtension "SPV_NV_ray_tracing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint CallableNV %main "main"
-; CHECK: OpEntryPoint CallableNV %main "main" [[launch_id:%\w+]]
+;CHECK: OpEntryPoint CallableNV %main "main" [[launch_id:%\w+]]
OpSource GLSL 460
OpSourceExtension "GL_EXT_nonuniform_qualifier"
OpSourceExtension "GL_NV_ray_tracing"
@@ -3541,9 +3148,8 @@ OpDecorate %sbo Binding 2
OpDecorate %images DescriptorSet 1
OpDecorate %images Binding 3
OpDecorate %images NonWritable
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-; CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
+)" + kImportDeco + R"(
+;CHECK: OpDecorate [[launch_id]] BuiltIn LaunchIdNV
%void = OpTypeVoid
%3 = OpTypeFunction %void
%uint = OpTypeInt 32 0
@@ -3565,11 +3171,9 @@ OpDecorate %images NonWritable
%v4float = OpTypeVector %float 4
%uint_0 = OpConstant %uint 0
%_ptr_Uniform_float = OpTypePointer Uniform %float
-)" + kInputGlobals + kOutputGlobals + R"(
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-; CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_uint:%\w+]] = OpConstantNull %uint
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -3580,72 +3184,71 @@ OpDecorate %images NonWritable
%23 = OpLoad %13 %22
%27 = OpImageRead %v4float %23 %25
%29 = OpCompositeExtract %float %27 0
+;CHECK-NOT: %20 = OpLoad %uint %19
+;CHECK-NOT: %22 = OpAccessChain %_ptr_UniformConstant_13 %images %20
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %25
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
+;CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
+;CHECK-NOT: %23 = OpLoad %13 %22
+;CHECK-NOT: %27 = OpImageRead %v4float %23 %25
+;CHECK-NOT: %29 = OpCompositeExtract %float %27 0
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %27
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
+;CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
%31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
OpStore %31 %29
-; CHECK-NOT: OpStore %31 %29
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %uint %25
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_48 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %uint {{%\w+}} {{%\w+}} [[null_uint]] {{%\w+}}
-; CHECK: %27 = OpAccessChain %_ptr_UniformConstant_13 %images {{%\w+}}
-; CHECK: %28 = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_binding_length %uint_1 %uint_3
-; CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_3 {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %27
-; CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %20
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_1 %uint_1 %uint_3 {{%\w+}} %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_51 %uint_0 %uint_1 %uint_3 {{%\w+}} {{%\w+}}
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %30 = OpCompositeExtract %float {{%\w+}} 0
-; CHECK: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpStore %31 %30
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_54 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
+;CHECK-NOT: %31 = OpAccessChain %_ptr_Uniform_float %sbo %int_1
+;CHECK-NOT: OpStore %31 %29
+;CHECK: {{%\w+}} = OpLoad %v3uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5318 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_55 {{%\w+}} %uint_1 %uint_2 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %31 %30
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs =
- kReadBindingLength + kStreamWrite6Ray + kReadDescInit;
+ // clang-format on
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) {
@@ -3680,12 +3283,12 @@ TEST_F(InstBindlessTest, InstBoundsInitSameBlockOpReplication) {
OpCapability Shader
OpCapability ShaderNonUniformEXT
OpCapability SampledImageArrayNonUniformIndexingEXT
+;CHECK: OpCapability Linkage
OpExtension "SPV_EXT_descriptor_indexing"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %inTexcoord %outColor
-; CHECK: OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %inTexcoord %outColor %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_EXT_nonuniform_qualifier"
@@ -3715,12 +3318,11 @@ OpDecorate %Uniforms Block
OpDecorate %uniforms DescriptorSet 1
OpDecorate %uniforms Binding 0
OpDecorate %outColor Location 0
-; CHECK: OpDecorate %63 NonUniform
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate [[desc_state_result:%\w+]] NonUniform
+;CHECK: OpDecorate {{%\w+}} NonUniform
+;CHECK: OpDecorate {{%\w+}} NonUniform
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+;CHECK: OpDecorate [[desc_state_result:%\w+]] NonUniform
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
@@ -3752,12 +3354,9 @@ OpDecorate %outColor Location 0
%_ptr_Output_v4float = OpTypePointer Output %v4float
%outColor = OpVariable %_ptr_Output_v4float Output
%float_0 = OpConstant %float 0
-)" + kOutputGlobals + R"(
-; CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-)" + kInputGlobals + R"(
-; CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
)";
- // clang-format on
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -3774,6 +3373,26 @@ OpStore %index %int_0
%32 = OpLoad %v2float %inTexcoord
%34 = OpImageSampleImplicitLod %v4float %28 %32
%36 = OpCompositeExtract %float %34 0
+;CHECK-NOT: %34 = OpImageSampleImplicitLod %v4float %28 %32
+;CHECK-NOT: %36 = OpCompositeExtract %float %34 0
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpBitcast %uint %19
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_80 {{%\w+}} %uint_1 %uint_3 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %21
+;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %26
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %32
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
OpStore %x %36
%39 = OpLoad %13 %uniformTex
%40 = OpLoad %23 %uniformSampler
@@ -3782,38 +3401,48 @@ OpStore %x %36
%47 = OpAccessChain %_ptr_Uniform_v2float %uniforms %int_0
%48 = OpLoad %v2float %47
%49 = OpFMul %v2float %42 %48
+;CHECK-NOT: %48 = OpLoad %v2float %47
+;CHECK-NOT: %49 = OpFMul %v2float %42 %48
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_88 {{%\w+}} %uint_1 %uint_0 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %v2float %47
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
+;CHECK: %49 = OpFMul %v2float %42 [[phi_result]]
%50 = OpImageSampleImplicitLod %v4float %41 %49
%51 = OpCompositeExtract %float %50 0
-; CHECK-NOT: %51 = OpCompositeExtract %float %50 0
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_0 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %v2float %47
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_87 %uint_1 %uint_1 %uint_0 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
-; CHECK: %49 = OpFMul %v2float %42 {{%\w+}}
-; CHECK: {{%\w+}} = OpSampledImage %27 %39 %40
-; CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 %uint_0
-; CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpLoad %13 %uniformTex
-; CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %40
-; CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %49
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_89 %uint_1 %uint_1 %uint_2 %uint_0 %uint_0
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-; CHECK: %51 = OpCompositeExtract %float {{%\w+}} 0
+OpStore %y %51
+;CHECK-NOT: %50 = OpImageSampleImplicitLod %v4float %41 %49
+;CHECK-NOT: %51 = OpCompositeExtract %float %50 0
+;CHECK: {{%\w+}} = OpSampledImage %27 %39 %40
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_90 {{%\w+}} %uint_1 %uint_2 %uint_0 %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %13 %uniformTex
+;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %40
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %49
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: %51 = OpCompositeExtract %float {{%\w+}} 0
OpStore %y %51
%54 = OpLoad %float %x
%55 = OpLoad %float %y
@@ -3822,13 +3451,11 @@ OpStore %outColor %57
OpReturn
OpFunctionEnd
)";
-
- const std::string new_funcs = kStreamWrite6Frag + kReadDescInit;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(defs + main_func + new_funcs,
- true, 7u, 23u, true, true, false,
- false, false);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(defs + kImportStub + main_func,
+ true, 23u);
}
TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) {
@@ -3870,143 +3497,145 @@ TEST_F(InstBindlessTest, MultipleUniformNonAggregateRefsNoDescInit) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
-;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %MainPs OriginUpperLeft
- OpSource HLSL 500
- OpName %MainPs "MainPs"
- OpName %PerViewPushConst_t "PerViewPushConst_t"
- OpMemberName %PerViewPushConst_t 0 "g_B"
- OpName %_ ""
- OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
- OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0"
- OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1"
- OpName %__0 ""
- OpName %g_tColor "g_tColor"
- OpName %g_sAniso "g_sAniso"
- OpName %i_vTextureCoords "i.vTextureCoords"
- OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
- OpMemberDecorate %PerViewPushConst_t 0 Offset 0
- OpDecorate %PerViewPushConst_t Block
- OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
- OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8
- OpDecorate %PerViewConstantBuffer_t Block
- OpDecorate %__0 DescriptorSet 0
- OpDecorate %__0 Binding 1
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 2
- OpDecorate %i_vTextureCoords Location 0
- OpDecorate %_entryPointOutput_vColor Location 0
- ;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
- ;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %uint = OpTypeInt 32 0
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+OpExecutionMode %MainPs OriginUpperLeft
+OpSource HLSL 500
+OpName %MainPs "MainPs"
+OpName %PerViewPushConst_t "PerViewPushConst_t"
+OpMemberName %PerViewPushConst_t 0 "g_B"
+OpName %_ ""
+OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
+OpMemberName %PerViewConstantBuffer_t 0 "g_TexOff0"
+OpMemberName %PerViewConstantBuffer_t 1 "g_TexOff1"
+OpName %__0 ""
+OpName %g_tColor "g_tColor"
+OpName %g_sAniso "g_sAniso"
+OpName %i_vTextureCoords "i.vTextureCoords"
+OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
+OpMemberDecorate %PerViewPushConst_t 0 Offset 0
+OpDecorate %PerViewPushConst_t Block
+OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
+OpMemberDecorate %PerViewConstantBuffer_t 1 Offset 8
+OpDecorate %PerViewConstantBuffer_t Block
+OpDecorate %__0 DescriptorSet 0
+OpDecorate %__0 Binding 1
+OpDecorate %g_tColor DescriptorSet 0
+OpDecorate %g_tColor Binding 0
+OpDecorate %g_sAniso DescriptorSet 0
+OpDecorate %g_sAniso Binding 2
+OpDecorate %i_vTextureCoords Location 0
+OpDecorate %_entryPointOutput_vColor Location 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%uint = OpTypeInt 32 0
%PerViewPushConst_t = OpTypeStruct %uint
%_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
- %_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
+%_ = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
- %bool = OpTypeBool
- %uint_0 = OpConstant %uint 0
+%bool = OpTypeBool
+%uint_0 = OpConstant %uint 0
%PerViewConstantBuffer_t = OpTypeStruct %v2float %v2float
%_ptr_Uniform_PerViewConstantBuffer_t = OpTypePointer Uniform %PerViewConstantBuffer_t
- %__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform
+%__0 = OpVariable %_ptr_Uniform_PerViewConstantBuffer_t Uniform
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %int_1 = OpConstant %int 1
- %49 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%int_1 = OpConstant %int 1
+%49 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_49 = OpTypePointer UniformConstant %49
- %g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant
- %53 = OpTypeSampler
+%g_tColor = OpVariable %_ptr_UniformConstant_49 UniformConstant
+%53 = OpTypeSampler
%_ptr_UniformConstant_53 = OpTypePointer UniformConstant %53
- %g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant
- %57 = OpTypeSampledImage %49
+%g_sAniso = OpVariable %_ptr_UniformConstant_53 UniformConstant
+%57 = OpTypeSampledImage %49
%_ptr_Input_v2float = OpTypePointer Input %v2float
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
- )" + kInputGlobals + kOutputGlobals + R"(
- ;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
- ;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
- ;CHECK: %v4uint = OpTypeVector %uint 4
- ;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
- %MainPs = OpFunction %void None %3
- %5 = OpLabel
- ;CHECK: [[desc_state_result:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_1 %uint_0
- ;CHECK: OpBranch %117
- ;CHECK: %117 = OpLabel
- ;CHECK: OpBranch %116
- ;CHECK: %116 = OpLabel
- %69 = OpLoad %v2float %i_vTextureCoords
- %82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
- %83 = OpLoad %uint %82
- %84 = OpINotEqual %bool %83 %uint_0
- OpSelectionMerge %91 None
- OpBranchConditional %84 %85 %88
- %85 = OpLabel
- %86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0
- %87 = OpLoad %v2float %86
- ;CHECK-NOT: %87 = OpLoad %v2float %86
- ;CHECK: %119 = OpIAdd %uint %uint_0 %uint_7
- ;CHECK: {{%\w+}} = OpULessThan %bool %119 [[desc_state_result]]
- ;CHECK: OpSelectionMerge {{%\w+}} None
- ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
- ;CHECK: {{%\w+}} = OpLoad %v2float %86
- ;CHECK: OpBranch {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
- ;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_71 %uint_4 %uint_0 %uint_1 %uint_0 %119 {{%\w+}}
- ;CHECK: OpBranch {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
- ;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
- OpBranch %91
- %88 = OpLabel
- %89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1
- %90 = OpLoad %v2float %89
- ;CHECK-NOT: %90 = OpLoad %v2float %89
- ;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_7
- ;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
- ;CHECK: OpSelectionMerge {{%\w+}} None
- ;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
- ;CHECK: {{%\w+}} = OpLoad %v2float %89
- ;CHECK: OpBranch {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
- ;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_75 %uint_4 %uint_0 %uint_1 %uint_0 {{%\w+}} {{%\w+}}
- ;CHECK: OpBranch {{%\w+}}
- ;CHECK: {{%\w+}} = OpLabel
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
+ )" + kImportStub + R"(
+%MainPs = OpFunction %void None %3
+%5 = OpLabel
+%69 = OpLoad %v2float %i_vTextureCoords
+%82 = OpAccessChain %_ptr_PushConstant_uint %_ %int_0
+%83 = OpLoad %uint %82
+%84 = OpINotEqual %bool %83 %uint_0
+OpSelectionMerge %91 None
+OpBranchConditional %84 %85 %88
+%85 = OpLabel
+%86 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_0
+%87 = OpLoad %v2float %86
+;CHECK-NOT: %87 = OpLoad %v2float %86
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[desc_state_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_72 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional [[desc_state_result]] {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %v2float %86
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
- OpBranch %91
- %91 = OpLabel
- %115 = OpPhi %v2float %87 %85 %90 %88
- ;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88
- ;CHECK: %115 = OpPhi %v2float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
- %95 = OpFAdd %v2float %69 %115
- %96 = OpLoad %49 %g_tColor
- %97 = OpLoad %53 %g_sAniso
- %98 = OpSampledImage %57 %96 %97
- %100 = OpImageSampleImplicitLod %v4float %98 %95
- OpStore %_entryPointOutput_vColor %100
- OpReturn
- OpFunctionEnd
-)" + kReadDescInit + kStreamWrite7Frag;
+OpBranch %91
+%88 = OpLabel
+%89 = OpAccessChain %_ptr_Uniform_v2float %__0 %int_1
+%90 = OpLoad %v2float %89
+;CHECK-NOT: %90 = OpLoad %v2float %89
+;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_7
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_76 {{%\w+}} %uint_0 %uint_1 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %v2float %89
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
+OpBranch %91
+%91 = OpLabel
+%115 = OpPhi %v2float %87 %85 %90 %88
+;CHECK-NOT: %115 = OpPhi %v2float %87 %85 %90 %88
+;CHECK: %115 = OpPhi %v2float {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+%95 = OpFAdd %v2float %69 %115
+%96 = OpLoad %49 %g_tColor
+%97 = OpLoad %53 %g_sAniso
+%98 = OpSampledImage %57 %96 %97
+%100 = OpImageSampleImplicitLod %v4float %98 %95
+OpStore %_entryPointOutput_vColor %100
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) {
@@ -4047,132 +3676,129 @@ TEST_F(InstBindlessTest, UniformArrayRefNoDescInit) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
- OpExecutionMode %MainPs OriginUpperLeft
- OpSource HLSL 500
- OpName %MainPs "MainPs"
- OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
- OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
- OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
- OpName %_ ""
- OpName %PerViewPushConst_t "PerViewPushConst_t"
- OpMemberName %PerViewPushConst_t 0 "g_c"
- OpName %__0 ""
- OpName %g_tColor "g_tColor"
- OpName %g_sAniso "g_sAniso"
- OpName %i_vTextureCoords "i.vTextureCoords"
- OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
- OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
- OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
- OpDecorate %_BindlessFastEnvMapCB_PS_t Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 2
- OpMemberDecorate %PerViewPushConst_t 0 Offset 0
- OpDecorate %PerViewPushConst_t Block
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- OpDecorate %i_vTextureCoords Location 0
- OpDecorate %_entryPointOutput_vColor Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %v3float = OpTypeVector %float 3
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
+OpExecutionMode %MainPs OriginUpperLeft
+OpSource HLSL 500
+OpName %MainPs "MainPs"
+OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
+OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
+OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
+OpName %_ ""
+OpName %PerViewPushConst_t "PerViewPushConst_t"
+OpMemberName %PerViewPushConst_t 0 "g_c"
+OpName %__0 ""
+OpName %g_tColor "g_tColor"
+OpName %g_sAniso "g_sAniso"
+OpName %i_vTextureCoords "i.vTextureCoords"
+OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
+OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
+OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
+OpDecorate %_BindlessFastEnvMapCB_PS_t Block
+OpDecorate %_ DescriptorSet 0
+OpDecorate %_ Binding 2
+OpMemberDecorate %PerViewPushConst_t 0 Offset 0
+OpDecorate %PerViewPushConst_t Block
+OpDecorate %g_tColor DescriptorSet 0
+OpDecorate %g_tColor Binding 0
+OpDecorate %g_sAniso DescriptorSet 0
+OpDecorate %g_sAniso Binding 1
+OpDecorate %i_vTextureCoords Location 0
+OpDecorate %_entryPointOutput_vColor Location 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%v3float = OpTypeVector %float 3
%mat4v3float = OpTypeMatrix %v3float 4
%PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
- %uint = OpTypeInt 32 0
- %uint_128 = OpConstant %uint 128
+%uint = OpTypeInt 32 0
+%uint_128 = OpConstant %uint 128
%_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
%_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
%_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
- %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
+%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
%PerViewPushConst_t = OpTypeStruct %uint
%_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
- %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
+%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
- %int_2 = OpConstant %int 2
+%int_2 = OpConstant %int 2
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %46 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%46 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
- %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
- %50 = OpTypeSampler
+%g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
+%50 = OpTypeSampler
%_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
- %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
- %54 = OpTypeSampledImage %46
+%g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
+%54 = OpTypeSampledImage %46
%_ptr_Input_v2float = OpTypePointer Input %v2float
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kInputGlobals + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: %v4uint = OpTypeVector %uint 4
-;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
- %MainPs = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_2 %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
- %66 = OpLoad %v2float %i_vTextureCoords
- %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
- %80 = OpLoad %uint %79
- %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
- %82 = OpLoad %v2float %81
-;CHECK-NOT: %82 = OpLoad %v2float %81
+;CHECK: %v4uint = OpTypeVector %uint 4
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
+)" + kImportStub + R"(
+%MainPs = OpFunction %void None %3
+%5 = OpLabel
+%66 = OpLoad %v2float %i_vTextureCoords
+%79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
+%80 = OpLoad %uint %79
+%81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
+%82 = OpLoad %v2float %81
+;CHECK-NOT: %82 = OpLoad %v2float %81
;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80
;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpLoad %v2float %81
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_78 %uint_4 %uint_0 %uint_2 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
- %86 = OpFAdd %v2float %66 %82
-;CHECK-NOT: %86 = OpFAdd %v2float %66 %82
-;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}}
- %87 = OpLoad %46 %g_tColor
- %88 = OpLoad %50 %g_sAniso
- %89 = OpSampledImage %54 %87 %88
- %91 = OpImageSampleImplicitLod %v4float %89 %86
- OpStore %_entryPointOutput_vColor %91
- OpReturn
- OpFunctionEnd
-)" + kReadDescInit + kStreamWrite7Frag;
+%86 = OpFAdd %v2float %66 %82
+;CHECK-NOT: %86 = OpFAdd %v2float %66 %82
+;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}}
+%87 = OpLoad %46 %g_tColor
+%88 = OpLoad %50 %g_sAniso
+%89 = OpSampledImage %54 %87 %88
+%91 = OpImageSampleImplicitLod %v4float %89 %86
+OpStore %_entryPointOutput_vColor %91
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) {
@@ -4183,129 +3809,131 @@ TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
-;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %MainPs OriginUpperLeft
- OpSource HLSL 500
- OpName %MainPs "MainPs"
- OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
- OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
- OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
- OpName %_ ""
- OpName %PerViewPushConst_t "PerViewPushConst_t"
- OpMemberName %PerViewPushConst_t 0 "g_c"
- OpName %__0 ""
- OpName %g_tColor "g_tColor"
- OpName %g_sAniso "g_sAniso"
- OpName %i_vTextureCoords "i.vTextureCoords"
- OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
- OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
- OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
- OpDecorate %_BindlessFastEnvMapCB_PS_t Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 2
- OpMemberDecorate %PerViewPushConst_t 0 Offset 0
- OpDecorate %PerViewPushConst_t Block
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 1
- OpDecorate %i_vTextureCoords Location 0
- OpDecorate %_entryPointOutput_vColor Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %v3float = OpTypeVector %float 3
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+OpExecutionMode %MainPs OriginUpperLeft
+OpSource HLSL 500
+OpName %MainPs "MainPs"
+OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
+OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
+OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
+OpName %_ ""
+OpName %PerViewPushConst_t "PerViewPushConst_t"
+OpMemberName %PerViewPushConst_t 0 "g_c"
+OpName %__0 ""
+OpName %g_tColor "g_tColor"
+OpName %g_sAniso "g_sAniso"
+OpName %i_vTextureCoords "i.vTextureCoords"
+OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
+OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
+OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
+OpDecorate %_BindlessFastEnvMapCB_PS_t Block
+OpDecorate %_ DescriptorSet 0
+OpDecorate %_ Binding 2
+OpMemberDecorate %PerViewPushConst_t 0 Offset 0
+OpDecorate %PerViewPushConst_t Block
+OpDecorate %g_tColor DescriptorSet 0
+OpDecorate %g_tColor Binding 0
+OpDecorate %g_sAniso DescriptorSet 0
+OpDecorate %g_sAniso Binding 1
+OpDecorate %i_vTextureCoords Location 0
+OpDecorate %_entryPointOutput_vColor Location 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%v3float = OpTypeVector %float 3
%mat4v3float = OpTypeMatrix %v3float 4
%PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
- %uint = OpTypeInt 32 0
- %uint_128 = OpConstant %uint 128
+%uint = OpTypeInt 32 0
+%uint_128 = OpConstant %uint 128
%_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
%_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
%_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
- %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
+%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
%PerViewPushConst_t = OpTypeStruct %uint
%_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
- %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
+%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
%_ptr_PushConstant_uint = OpTypePointer PushConstant %uint
- %int_2 = OpConstant %int 2
+%int_2 = OpConstant %int 2
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %46 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%46 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
- %g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
- %50 = OpTypeSampler
+%g_tColor = OpVariable %_ptr_UniformConstant_46 UniformConstant
+%50 = OpTypeSampler
%_ptr_UniformConstant_50 = OpTypePointer UniformConstant %50
- %g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
- %54 = OpTypeSampledImage %46
+%g_sAniso = OpVariable %_ptr_UniformConstant_50 UniformConstant
+%54 = OpTypeSampledImage %46
%_ptr_Input_v2float = OpTypePointer Input %v2float
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kInputGlobals + kOutputGlobals + R"(
+;CHECK: %v4uint = OpTypeVector %uint 4
;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: %v4uint = OpTypeVector %uint 4
;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
- %MainPs = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_2 %uint_0
-;CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_0 %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
- %66 = OpLoad %v2float %i_vTextureCoords
- %79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
- %80 = OpLoad %uint %79
- %81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
- %82 = OpLoad %v2float %81
- %86 = OpFAdd %v2float %66 %82
+)" + kImportStub + R"(
+%MainPs = OpFunction %void None %3
+%5 = OpLabel
+%66 = OpLoad %v2float %i_vTextureCoords
+%79 = OpAccessChain %_ptr_PushConstant_uint %__0 %int_0
+%80 = OpLoad %uint %79
+%81 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %80 %int_2
+%82 = OpLoad %v2float %81
+%86 = OpFAdd %v2float %66 %82
;CHECK-NOT: %82 = OpLoad %v2float %81
;CHECK-NOT: %86 = OpFAdd %v2float %66 %82
;CHECK: {{%\w+}} = OpIMul %uint %uint_80 %80
;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_79 {{%\w+}} %uint_0 %uint_2 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpLoad %v2float %81
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_78 %uint_4 %uint_0 %uint_2 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
;CHECK: %86 = OpFAdd %v2float %66 {{%\w+}}
- %87 = OpLoad %46 %g_tColor
- %88 = OpLoad %50 %g_sAniso
- %89 = OpSampledImage %54 %87 %88
- %91 = OpImageSampleImplicitLod %v4float %89 %86
- OpStore %_entryPointOutput_vColor %91
+%87 = OpLoad %46 %g_tColor
+%88 = OpLoad %50 %g_sAniso
+%89 = OpSampledImage %54 %87 %88
+%91 = OpImageSampleImplicitLod %v4float %89 %86
+OpStore %_entryPointOutput_vColor %91
;CHECK-NOT: %91 = OpImageSampleImplicitLod %v4float %89 %86
;CHECK-NOT: OpStore %_entryPointOutput_vColor %91
-;CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_84 {{%\w+}} %uint_0 %uint_0 %uint_0 %uint_0
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
@@ -4314,20 +3942,18 @@ TEST_F(InstBindlessTest, UniformArrayRefWithDescInit) {
;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %86
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_83 %uint_1 %uint_0 %uint_0 %uint_0 %uint_0 %uint_0
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
;CHECK: OpStore %_entryPointOutput_vColor {{%\w+}}
- OpReturn
- OpFunctionEnd
-)" + kReadDescInit + kStreamWrite7Frag;
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
- true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, Descriptor16BitIdxRef) {
@@ -4338,124 +3964,107 @@ TEST_F(InstBindlessTest, Descriptor16BitIdxRef) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability Int16
- OpCapability StoragePushConstant16
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
-;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_output_buffer %gl_FragCoord %inst_bindless_input_buffer
- OpExecutionMode %MainPs OriginUpperLeft
- OpSource HLSL 500
- OpName %MainPs "MainPs"
- OpName %g_tColor "g_tColor"
- OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
- OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
- OpName %_ ""
- OpName %g_sAniso "g_sAniso"
- OpName %i_vTextureCoords "i.vTextureCoords"
- OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
- OpDecorate %g_tColor DescriptorSet 1
- OpDecorate %g_tColor Binding 2
- OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
- OpDecorate %PerViewConstantBuffer_t Block
- OpDecorate %g_sAniso DescriptorSet 1
- OpDecorate %g_sAniso Binding 2
- OpDecorate %i_vTextureCoords Location 0
- OpDecorate %_entryPointOutput_vColor Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-)" + kInputDecorations + R"(
- %void = OpTypeVoid
- %10 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %16 = OpTypeImage %float 2D 0 0 0 1 Unknown
- %uint = OpTypeInt 32 0
- %uint_128 = OpConstant %uint 128
+OpCapability Shader
+OpCapability Int16
+OpCapability StoragePushConstant16
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %g_tColor %_ %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+OpExecutionMode %MainPs OriginUpperLeft
+OpSource HLSL 500
+OpName %MainPs "MainPs"
+OpName %g_tColor "g_tColor"
+OpName %PerViewConstantBuffer_t "PerViewConstantBuffer_t"
+OpMemberName %PerViewConstantBuffer_t 0 "g_nDataIdx"
+OpName %_ ""
+OpName %g_sAniso "g_sAniso"
+OpName %i_vTextureCoords "i.vTextureCoords"
+OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
+OpDecorate %g_tColor DescriptorSet 1
+OpDecorate %g_tColor Binding 2
+OpMemberDecorate %PerViewConstantBuffer_t 0 Offset 0
+OpDecorate %PerViewConstantBuffer_t Block
+OpDecorate %g_sAniso DescriptorSet 1
+OpDecorate %g_sAniso Binding 2
+OpDecorate %i_vTextureCoords Location 0
+OpDecorate %_entryPointOutput_vColor Location 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%10 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%16 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%uint = OpTypeInt 32 0
+%uint_128 = OpConstant %uint 128
%_arr_16_uint_128 = OpTypeArray %16 %uint_128
%_ptr_UniformConstant__arr_16_uint_128 = OpTypePointer UniformConstant %_arr_16_uint_128
- %g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
- %ushort = OpTypeInt 16 0
+%g_tColor = OpVariable %_ptr_UniformConstant__arr_16_uint_128 UniformConstant
+%ushort = OpTypeInt 16 0
%PerViewConstantBuffer_t = OpTypeStruct %ushort
%_ptr_PushConstant_PerViewConstantBuffer_t = OpTypePointer PushConstant %PerViewConstantBuffer_t
- %_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
+%_ = OpVariable %_ptr_PushConstant_PerViewConstantBuffer_t PushConstant
%_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort
%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
- %25 = OpTypeSampler
+%25 = OpTypeSampler
%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25
- %g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
- %27 = OpTypeSampledImage %16
+%g_sAniso = OpVariable %_ptr_UniformConstant_25 UniformConstant
+%27 = OpTypeSampledImage %16
%_ptr_Input_v2float = OpTypePointer Input %v2float
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
-)" + kInputGlobals + R"(
- %MainPs = OpFunction %void None %10
- %30 = OpLabel
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: OpBranch %39
-;CHECK: %39 = OpLabel
- %31 = OpLoad %v2float %i_vTextureCoords
- %32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0
- %33 = OpLoad %ushort %32
- %34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33
- %35 = OpLoad %16 %34
- %36 = OpLoad %25 %g_sAniso
- %37 = OpSampledImage %27 %35 %36
- %38 = OpImageSampleImplicitLod %v4float %37 %31
- OpStore %_entryPointOutput_vColor %38
-;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31
-;CHECK-NOT: OpStore %_entryPointOutput_vColor %38
-;CHECK: %41 = OpUConvert %uint %33
-;CHECK: {{%\w+}} = OpULessThan %bool %41 %uint_128
-;CHECK: OpSelectionMerge {{%\w+}} None
-;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpLoad %16 %34
-;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
-;CHECK: {{%\w+}} = OpUConvert %uint %33
-;CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_1 %uint_2 {{%\w+}}
-;CHECK: {{%\w+}} = OpULessThan %bool %uint_0 {{%\w+}}
-;CHECK: OpSelectionMerge {{%\w+}} None
-;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpLoad %16 %34
-;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
-;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpUConvert %uint %33
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_60 %uint_1 %uint_1 %uint_2 {{%\w+}} %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: [[phi_result_1:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
-;CHECK: OpBranch %44
-;CHECK: %46 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_6 %uint_60 %uint_0 %uint_1 %uint_2 %41 %uint_128
-;CHECK: OpBranch %44
-;CHECK: %44 = OpLabel
-;CHECK: [[phi_result_2:%\w+]] = OpPhi %v4float [[phi_result_1]] {{%\w+}} [[null_v4float]] %46
-;CHECK: OpStore %_entryPointOutput_vColor [[phi_result_2]]
- OpReturn
- OpFunctionEnd
-)" + kStreamWrite6Frag + kReadDescInit;
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+)" + kImportStub + R"(
+%MainPs = OpFunction %void None %10
+%30 = OpLabel
+;CHECK: OpBranch %39
+;CHECK: %39 = OpLabel
+%31 = OpLoad %v2float %i_vTextureCoords
+%32 = OpAccessChain %_ptr_PushConstant_ushort %_ %int_0
+%33 = OpLoad %ushort %32
+%34 = OpAccessChain %_ptr_UniformConstant_16 %g_tColor %33
+%35 = OpLoad %16 %34
+%36 = OpLoad %25 %g_sAniso
+%37 = OpSampledImage %27 %35 %36
+%38 = OpImageSampleImplicitLod %v4float %37 %31
+OpStore %_entryPointOutput_vColor %38
+;CHECK-NOT: %38 = OpImageSampleImplicitLod %v4float %37 %31
+;CHECK-NOT: OpStore %_entryPointOutput_vColor %38
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpUConvert %uint %33
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_1 %uint_2 {{%\w+}} %uint_0
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %16 %34
+;CHECK: {{%\w+}} = OpSampledImage %27 {{%\w+}} %36
+;CHECK: {{%\w+}} = OpImageSampleImplicitLod %v4float {{%\w+}} %31
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %_entryPointOutput_vColor [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, true, true,
- false, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformArray16bitIdxRef) {
@@ -4496,136 +4105,133 @@ TEST_F(InstBindlessTest, UniformArray16bitIdxRef) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability Int16
- OpCapability StoragePushConstant16
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
-;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %MainPs OriginUpperLeft
- OpSource HLSL 500
- OpName %MainPs "MainPs"
- OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
- OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
- OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
- OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
- OpName %_ ""
- OpName %PerViewPushConst_t "PerViewPushConst_t"
- OpMemberName %PerViewPushConst_t 0 "g_c"
- OpName %__0 ""
- OpName %g_tColor "g_tColor"
- OpName %g_sAniso "g_sAniso"
- OpName %i_vTextureCoords "i.vTextureCoords"
- OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
- OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
- OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
- OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
- OpDecorate %_BindlessFastEnvMapCB_PS_t Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpMemberDecorate %PerViewPushConst_t 0 Offset 0
- OpDecorate %PerViewPushConst_t Block
- OpDecorate %g_tColor DescriptorSet 0
- OpDecorate %g_tColor Binding 0
- OpDecorate %g_sAniso DescriptorSet 0
- OpDecorate %g_sAniso Binding 0
- OpDecorate %i_vTextureCoords Location 0
- OpDecorate %_entryPointOutput_vColor Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %14 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
- %v4float = OpTypeVector %float 4
- %v3float = OpTypeVector %float 3
+OpCapability Shader
+OpCapability Int16
+OpCapability StoragePushConstant16
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor
+;CHECK: OpEntryPoint Fragment %MainPs "MainPs" %_ %__0 %g_tColor %g_sAniso %i_vTextureCoords %_entryPointOutput_vColor %gl_FragCoord
+OpExecutionMode %MainPs OriginUpperLeft
+OpSource HLSL 500
+OpName %MainPs "MainPs"
+OpName %PerBatchEnvMapConstantBuffer_t "PerBatchEnvMapConstantBuffer_t"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 0 "g_matEnvMapWorldToLocal"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 1 "g_vEnvironmentMapBoxMins"
+OpMemberName %PerBatchEnvMapConstantBuffer_t 2 "g_TexOff"
+OpName %_BindlessFastEnvMapCB_PS_t "_BindlessFastEnvMapCB_PS_t"
+OpMemberName %_BindlessFastEnvMapCB_PS_t 0 "g_envMapConstants"
+OpName %_ ""
+OpName %PerViewPushConst_t "PerViewPushConst_t"
+OpMemberName %PerViewPushConst_t 0 "g_c"
+OpName %__0 ""
+OpName %g_tColor "g_tColor"
+OpName %g_sAniso "g_sAniso"
+OpName %i_vTextureCoords "i.vTextureCoords"
+OpName %_entryPointOutput_vColor "@entryPointOutput.vColor"
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 RowMajor
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 Offset 0
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 0 MatrixStride 16
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 1 Offset 48
+OpMemberDecorate %PerBatchEnvMapConstantBuffer_t 2 Offset 64
+OpDecorate %_arr_PerBatchEnvMapConstantBuffer_t_uint_128 ArrayStride 80
+OpMemberDecorate %_BindlessFastEnvMapCB_PS_t 0 Offset 0
+OpDecorate %_BindlessFastEnvMapCB_PS_t Block
+OpDecorate %_ DescriptorSet 0
+OpDecorate %_ Binding 0
+OpMemberDecorate %PerViewPushConst_t 0 Offset 0
+OpDecorate %PerViewPushConst_t Block
+OpDecorate %g_tColor DescriptorSet 0
+OpDecorate %g_tColor Binding 0
+OpDecorate %g_sAniso DescriptorSet 0
+OpDecorate %g_sAniso Binding 0
+OpDecorate %i_vTextureCoords Location 0
+OpDecorate %_entryPointOutput_vColor Location 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%14 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%v4float = OpTypeVector %float 4
+%v3float = OpTypeVector %float 3
%mat4v3float = OpTypeMatrix %v3float 4
%PerBatchEnvMapConstantBuffer_t = OpTypeStruct %mat4v3float %v4float %v2float
- %uint = OpTypeInt 32 0
- %uint_128 = OpConstant %uint 128
+%uint = OpTypeInt 32 0
+%uint_128 = OpConstant %uint 128
%_arr_PerBatchEnvMapConstantBuffer_t_uint_128 = OpTypeArray %PerBatchEnvMapConstantBuffer_t %uint_128
%_BindlessFastEnvMapCB_PS_t = OpTypeStruct %_arr_PerBatchEnvMapConstantBuffer_t_uint_128
%_ptr_Uniform__BindlessFastEnvMapCB_PS_t = OpTypePointer Uniform %_BindlessFastEnvMapCB_PS_t
- %_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %ushort = OpTypeInt 16 0
+%_ = OpVariable %_ptr_Uniform__BindlessFastEnvMapCB_PS_t Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%ushort = OpTypeInt 16 0
%PerViewPushConst_t = OpTypeStruct %ushort
%_ptr_PushConstant_PerViewPushConst_t = OpTypePointer PushConstant %PerViewPushConst_t
- %__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
+%__0 = OpVariable %_ptr_PushConstant_PerViewPushConst_t PushConstant
%_ptr_PushConstant_ushort = OpTypePointer PushConstant %ushort
- %int_2 = OpConstant %int 2
+%int_2 = OpConstant %int 2
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %30 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%30 = OpTypeImage %float 2D 0 0 0 1 Unknown
%_ptr_UniformConstant_30 = OpTypePointer UniformConstant %30
- %g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant
- %32 = OpTypeSampler
+%g_tColor = OpVariable %_ptr_UniformConstant_30 UniformConstant
+%32 = OpTypeSampler
%_ptr_UniformConstant_32 = OpTypePointer UniformConstant %32
- %g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant
- %34 = OpTypeSampledImage %30
+%g_sAniso = OpVariable %_ptr_UniformConstant_32 UniformConstant
+%34 = OpTypeSampledImage %30
%_ptr_Input_v2float = OpTypePointer Input %v2float
%i_vTextureCoords = OpVariable %_ptr_Input_v2float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_vColor = OpVariable %_ptr_Output_v4float Output
-)" + kInputGlobals + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK:%gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
- %MainPs = OpFunction %void None %14
- %37 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_0 %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
- %38 = OpLoad %v2float %i_vTextureCoords
- %39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0
- %40 = OpLoad %ushort %39
- %41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2
- %42 = OpLoad %v2float %41
- %43 = OpFAdd %v2float %38 %42
-;CHECK-NOT: %42 = OpLoad %v2float %41
-;CHECK-NOT: %43 = OpFAdd %v2float %38 %42
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
+)" + kImportStub + R"(
+%MainPs = OpFunction %void None %14
+%37 = OpLabel
+%38 = OpLoad %v2float %i_vTextureCoords
+%39 = OpAccessChain %_ptr_PushConstant_ushort %__0 %int_0
+%40 = OpLoad %ushort %39
+%41 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %40 %int_2
+%42 = OpLoad %v2float %41
+%43 = OpFAdd %v2float %38 %42
+;CHECK-NOT: %42 = OpLoad %v2float %41
+;CHECK-NOT: %43 = OpFAdd %v2float %38 %42
;CHECK: {{%\w+}} = OpUConvert %uint %40
;CHECK: {{%\w+}} = OpIMul %uint %uint_80 {{%\w+}}
;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_64
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_82 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpLoad %v2float %41
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_81 %uint_4 %uint_0 %uint_0 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: {{%\w+}} = OpPhi %v2float {{%\w+}} {{%\w+}} [[null_v2float]] {{%\w+}}
;CHECK: %43 = OpFAdd %v2float %38 {{%\w+}}
- %44 = OpLoad %30 %g_tColor
- %45 = OpLoad %32 %g_sAniso
- %46 = OpSampledImage %34 %44 %45
- %47 = OpImageSampleImplicitLod %v4float %46 %43
- OpStore %_entryPointOutput_vColor %47
- OpReturn
- OpFunctionEnd
- )" + kReadDescInit + kStreamWrite7Frag;
+%44 = OpLoad %30 %g_tColor
+%45 = OpLoad %32 %g_sAniso
+%46 = OpSampledImage %34 %44 %45
+%47 = OpImageSampleImplicitLod %v4float %46 %43
+OpStore %_entryPointOutput_vColor %47
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) {
@@ -4649,102 +4255,98 @@ TEST_F(InstBindlessTest, UniformMatrixRefRowMajor) {
// clang-format off
std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
-;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex
- OpSource GLSL 450
- OpSourceExtension "GL_EXT_scalar_block_layout"
- OpName %main "main"
- OpName %v_vtxResult "v_vtxResult"
- OpName %Block "Block"
- OpMemberName %Block 0 "var"
- OpName %_ ""
- OpName %a_position "a_position"
- OpDecorate %v_vtxResult RelaxedPrecision
- OpDecorate %v_vtxResult Location 0
- OpMemberDecorate %Block 0 RowMajor
- OpMemberDecorate %Block 0 RelaxedPrecision
- OpMemberDecorate %Block 0 Offset 0
- OpMemberDecorate %Block 0 MatrixStride 16
- OpDecorate %Block Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpDecorate %21 RelaxedPrecision
-;CHECK-NOT: OpDecorate %21 RelaxedPrecision
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
+;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_scalar_block_layout"
+OpName %main "main"
+OpName %v_vtxResult "v_vtxResult"
+OpName %Block "Block"
+OpMemberName %Block 0 "var"
+OpName %_ ""
+OpName %a_position "a_position"
+OpDecorate %v_vtxResult RelaxedPrecision
+OpDecorate %v_vtxResult Location 0
+OpMemberDecorate %Block 0 RowMajor
+OpMemberDecorate %Block 0 RelaxedPrecision
+OpMemberDecorate %Block 0 Offset 0
+OpMemberDecorate %Block 0 MatrixStride 16
+OpDecorate %Block Block
+OpDecorate %_ DescriptorSet 0
+OpDecorate %_ Binding 0
+OpDecorate %21 RelaxedPrecision
+;CHECK-NOT: OpDecorate %21 RelaxedPrecision
;CHECK: OpDecorate %v_vtxResult RelaxedPrecision
;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision
- OpDecorate %a_position Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + R"(
-;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
-)" + kOutputDecorations + R"(
+OpDecorate %a_position Location 0
+)" + kImportDeco + R"(
;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
+;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
%_ptr_Output_float = OpTypePointer Output %float
%v_vtxResult = OpVariable %_ptr_Output_float Output
- %v2float = OpTypeVector %float 2
+%v2float = OpTypeVector %float 2
%mat4v2float = OpTypeMatrix %v2float 4
- %Block = OpTypeStruct %mat4v2float
+%Block = OpTypeStruct %mat4v2float
%_ptr_Uniform_Block = OpTypePointer Uniform %Block
- %_ = OpVariable %_ptr_Uniform_Block Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
+%_ = OpVariable %_ptr_Uniform_Block Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_2 = OpConstant %int 2
+%uint = OpTypeInt 32 0
+%uint_1 = OpConstant %uint 1
%_ptr_Uniform_float = OpTypePointer Uniform %float
- %v4float = OpTypeVector %float 4
+%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
- %a_position = OpVariable %_ptr_Input_v4float Input
-)" + kInputGlobals + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
-;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
-;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
+%a_position = OpVariable %_ptr_Input_v4float Input
+;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
+;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
+;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
;CHECK: [[null_float:%\w+]] = OpConstantNull %float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: [[desc_state:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_0 %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
- %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
- %21 = OpLoad %float %20
-;CHECK-NOT: %21 = OpLoad %float %20
+%20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
+%21 = OpLoad %float %20
+;CHECK-NOT: %21 = OpLoad %float %20
;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_2
;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %uint_1
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} [[desc_state]]
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
-;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[load_result]] = OpLoad %float %20
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_45 %uint_4 %uint_0 %uint_0 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}}
- OpStore %v_vtxResult %21
-;CHECK-NOT: OpStore %v_vtxResult %21
-;CHECK: OpStore %v_vtxResult [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kReadDescInit + kStreamWrite7Vert;
+OpStore %v_vtxResult %21
+;CHECK-NOT: OpStore %v_vtxResult %21$
+;CHECK: OpStore %v_vtxResult [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) {
@@ -4768,103 +4370,99 @@ TEST_F(InstBindlessTest, UniformMatrixRefColumnMajor) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
-;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex
- OpSource GLSL 450
- OpSourceExtension "GL_EXT_scalar_block_layout"
- OpName %main "main"
- OpName %v_vtxResult "v_vtxResult"
- OpName %Block "Block"
- OpMemberName %Block 0 "var"
- OpName %_ ""
- OpName %a_position "a_position"
- OpDecorate %v_vtxResult RelaxedPrecision
- OpDecorate %v_vtxResult Location 0
- OpMemberDecorate %Block 0 ColMajor
- OpMemberDecorate %Block 0 RelaxedPrecision
- OpMemberDecorate %Block 0 Offset 0
- OpMemberDecorate %Block 0 MatrixStride 8
- OpDecorate %Block Block
- OpDecorate %_ DescriptorSet 0
- OpDecorate %_ Binding 0
- OpDecorate %21 RelaxedPrecision
-;CHECK-NOT: OpDecorate %21 RelaxedPrecision
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
+;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_scalar_block_layout"
+OpName %main "main"
+OpName %v_vtxResult "v_vtxResult"
+OpName %Block "Block"
+OpMemberName %Block 0 "var"
+OpName %_ ""
+OpName %a_position "a_position"
+OpDecorate %v_vtxResult RelaxedPrecision
+OpDecorate %v_vtxResult Location 0
+OpMemberDecorate %Block 0 ColMajor
+OpMemberDecorate %Block 0 RelaxedPrecision
+OpMemberDecorate %Block 0 Offset 0
+OpMemberDecorate %Block 0 MatrixStride 8
+OpDecorate %Block Block
+OpDecorate %_ DescriptorSet 0
+OpDecorate %_ Binding 0
+OpDecorate %21 RelaxedPrecision
+;CHECK-NOT: OpDecorate %21 RelaxedPrecision
;CHECK: OpDecorate %v_vtxResult RelaxedPrecision
;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision
- OpDecorate %a_position Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + R"(
-;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
-)" + kOutputDecorations + R"(
+OpDecorate %a_position Location 0
+)" + kImportDeco + R"(
;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
+;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
%_ptr_Output_float = OpTypePointer Output %float
%v_vtxResult = OpVariable %_ptr_Output_float Output
- %v2float = OpTypeVector %float 2
+%v2float = OpTypeVector %float 2
%mat4v2float = OpTypeMatrix %v2float 4
- %Block = OpTypeStruct %mat4v2float
+%Block = OpTypeStruct %mat4v2float
%_ptr_Uniform_Block = OpTypePointer Uniform %Block
- %_ = OpVariable %_ptr_Uniform_Block Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %uint = OpTypeInt 32 0
- %uint_1 = OpConstant %uint 1
+%_ = OpVariable %_ptr_Uniform_Block Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_2 = OpConstant %int 2
+%uint = OpTypeInt 32 0
+%uint_1 = OpConstant %uint 1
%_ptr_Uniform_float = OpTypePointer Uniform %float
- %v4float = OpTypeVector %float 4
+%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
- %a_position = OpVariable %_ptr_Input_v4float Input
-)" + kInputGlobals + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
-;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
-;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
+%a_position = OpVariable %_ptr_Input_v4float Input
+;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
+;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
+;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
;CHECK: [[null_float:%\w+]] = OpConstantNull %float
+)" + kImportStub + R"(
%main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: [[desc_state:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_0 %uint_0
-;CHECK: OpBranch %26
-;CHECK: %26 = OpLabel
-;CHECK: OpBranch %25
-;CHECK: %25 = OpLabel
- %20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
- %21 = OpLoad %float %20
-;CHECK-NOT: %21 = OpLoad %float %20
-;CHECK: %29 = OpIMul %uint %uint_8 %int_2
-;CHECK: %30 = OpIAdd %uint %uint_0 %29
-;CHECK: %32 = OpIMul %uint %uint_4 %uint_1
-;CHECK: %33 = OpIAdd %uint %30 %32
-;CHECK: %35 = OpIAdd %uint %33 %uint_3
-;CHECK: {{%\w+}} = OpULessThan %bool %35 [[desc_state]]
+%5 = OpLabel
+%20 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %int_2 %uint_1
+%21 = OpLoad %float %20
+;CHECK-NOT: %21 = OpLoad %float %20
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpIMul %uint %uint_8 %int_2
+;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
+;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %uint_1
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_46 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
-;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK:[[load_result]] = OpLoad %float %20
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_45 %uint_4 %uint_0 %uint_0 %uint_0 %35 {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[phi_result]] = OpPhi %float [[load_result]] {{%\w+}} [[null_float]] {{%\w+}}
- OpStore %v_vtxResult %21
-;CHECK-NOT: OpStore %v_vtxResult %21
+OpStore %v_vtxResult %21
+;CHECK-NOT: OpStore %v_vtxResult %21$
;CHECK: OpStore %v_vtxResult [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kReadDescInit + kStreamWrite7Vert;
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
ValidatorOptions()->uniform_buffer_standard_layout = true;
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) {
@@ -4888,109 +4486,103 @@ TEST_F(InstBindlessTest, UniformMatrixVecRefRowMajor) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
-;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex
- OpSource GLSL 450
- OpSourceExtension "GL_EXT_scalar_block_layout"
- OpName %main "main"
- OpName %v_vtxResult "v_vtxResult"
- OpName %Block "Block"
- OpMemberName %Block 0 "var"
- OpName %_ ""
- OpName %a_position "a_position"
- OpDecorate %v_vtxResult Location 0
- OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32
- OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128
- OpMemberDecorate %Block 0 RowMajor
- OpMemberDecorate %Block 0 RelaxedPrecision
- OpMemberDecorate %Block 0 Offset 0
- OpMemberDecorate %Block 0 MatrixStride 16
- OpDecorate %Block Block
- OpDecorate %_ DescriptorSet 3
- OpDecorate %_ Binding 7
- OpDecorate %26 RelaxedPrecision
-;CHECK-NOT: OpDecorate %26 RelaxedPrecision
+OpCapability Shader
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position
+;CHECK: OpEntryPoint Vertex %main "main" %v_vtxResult %_ %a_position %gl_VertexIndex %gl_InstanceIndex
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_scalar_block_layout"
+OpName %main "main"
+OpName %v_vtxResult "v_vtxResult"
+OpName %Block "Block"
+OpMemberName %Block 0 "var"
+OpName %_ ""
+OpName %a_position "a_position"
+OpDecorate %v_vtxResult Location 0
+OpDecorate %_arr_mat2v2float_uint_4 ArrayStride 32
+OpDecorate %_arr__arr_mat2v2float_uint_4_uint_3 ArrayStride 128
+OpMemberDecorate %Block 0 RowMajor
+OpMemberDecorate %Block 0 RelaxedPrecision
+OpMemberDecorate %Block 0 Offset 0
+OpMemberDecorate %Block 0 MatrixStride 16
+OpDecorate %Block Block
+OpDecorate %_ DescriptorSet 3
+OpDecorate %_ Binding 7
+OpDecorate %26 RelaxedPrecision
+;CHECK-NOT: OpDecorate %26 RelaxedPrecision
;CHECK: OpDecorate [[phi_result:%\w+]] RelaxedPrecision
- OpDecorate %a_position Location 0
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kInputDecorations + R"(
-;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
-)" + kOutputDecorations + R"(
+OpDecorate %a_position Location 0
+)" + kImportDeco + R"(
;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v2float = OpTypeVector %float 2
+;CHECK: OpDecorate [[load_result:%\w+]] RelaxedPrecision
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
%_ptr_Output_v2float = OpTypePointer Output %v2float
%v_vtxResult = OpVariable %_ptr_Output_v2float Output
%mat2v2float = OpTypeMatrix %v2float 2
- %uint = OpTypeInt 32 0
- %uint_4 = OpConstant %uint 4
+%uint = OpTypeInt 32 0
+%uint_4 = OpConstant %uint 4
%_arr_mat2v2float_uint_4 = OpTypeArray %mat2v2float %uint_4
- %uint_3 = OpConstant %uint 3
+%uint_3 = OpConstant %uint 3
%_arr__arr_mat2v2float_uint_4_uint_3 = OpTypeArray %_arr_mat2v2float_uint_4 %uint_3
- %Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3
+%Block = OpTypeStruct %_arr__arr_mat2v2float_uint_4_uint_3
%_ptr_Uniform_Block = OpTypePointer Uniform %Block
- %_ = OpVariable %_ptr_Uniform_Block Uniform
- %int = OpTypeInt 32 1
- %int_0 = OpConstant %int 0
- %int_2 = OpConstant %int 2
- %int_3 = OpConstant %int 3
- %int_1 = OpConstant %int 1
+%_ = OpVariable %_ptr_Uniform_Block Uniform
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%int_2 = OpConstant %int 2
+%int_3 = OpConstant %int 3
+%int_1 = OpConstant %int 1
%_ptr_Uniform_v2float = OpTypePointer Uniform %v2float
- %v4float = OpTypeVector %float 4
+%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
- %a_position = OpVariable %_ptr_Input_v4float Input
-)" + kInputGlobals + kOutputGlobals + R"(
-;CHECK:%_ptr_Input_uint = OpTypePointer Input %uint
-;CHECK:%gl_VertexIndex = OpVariable %_ptr_Input_uint Input
-;CHECK:%gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
+%a_position = OpVariable %_ptr_Input_v4float Input
+;CHECK: %_ptr_Input_uint = OpTypePointer Input %uint
+;CHECK: %gl_VertexIndex = OpVariable %_ptr_Input_uint Input
+;CHECK: %gl_InstanceIndex = OpVariable %_ptr_Input_uint Input
;CHECK: [[null_v2float:%\w+]] = OpConstantNull %v2float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: [[desc_state:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_3 %uint_7 %uint_0
-;CHECK: OpBranch %31
-;CHECK: %31 = OpLabel
-;CHECK: OpBranch %30
-;CHECK: %30 = OpLabel
- %25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1
- %26 = OpLoad %v2float %25
- OpStore %v_vtxResult %26
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+%25 = OpAccessChain %_ptr_Uniform_v2float %_ %int_0 %int_2 %int_3 %int_1
+;CHECK: {{%\w+}} = OpIMul %uint %uint_128 %int_2
+;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
+;CHECK: {{%\w+}} = OpIMul %uint %uint_32 %int_3
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpIMul %uint %uint_4 %int_1
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_19
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[desc_state:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_52 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}}
+%26 = OpLoad %v2float %25
+OpStore %v_vtxResult %26
;CHECK-NOT: %26 = OpLoad %v2float %25
-;CHECK-NOT: OpStore %v_vtxResult %26
-;CHECK: %34 = OpIMul %uint %uint_128 %int_2
-;CHECK: %35 = OpIAdd %uint %uint_0 %34
-;CHECK: %37 = OpIMul %uint %uint_32 %int_3
-;CHECK: %38 = OpIAdd %uint %35 %37
-;CHECK: %40 = OpIMul %uint %uint_4 %int_1
-;CHECK: %41 = OpIAdd %uint %38 %40
-;CHECK: %43 = OpIAdd %uint %41 %uint_19
-;CHECK: {{%\w+}} = OpULessThan %bool %43 [[desc_state]]
+;CHECK-NOT: OpStore %v_vtxResult %26
;CHECK: OpSelectionMerge {{%\w+}} None
-;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpBranchConditional [[desc_state]] {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[load_result]] = OpLoad %v2float %25
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_51 %uint_4 %uint_3 %uint_7 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[phi_result]] = OpPhi %v2float [[load_result]] {{%\w+}} [[null_v2float]] {{%\w+}}
;CHECK: OpStore %v_vtxResult [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kReadDescInit + kStreamWrite7Vert;
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, false, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, ImageBufferOOBRead) {
@@ -5007,86 +4599,76 @@ TEST_F(InstBindlessTest, ImageBufferOOBRead) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability ImageBuffer
-;CHECK: OpCapability ImageQuery
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %x %s %ii
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %x "x"
- OpName %s "s"
- OpName %ii "ii"
- OpDecorate %x Location 11
- OpDecorate %s DescriptorSet 3
- OpDecorate %s Binding 7
- OpDecorate %s NonWritable
- OpDecorate %ii Flat
- OpDecorate %ii Location 13
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %x = OpVariable %_ptr_Output_v4float Output
- %10 = OpTypeImage %float Buffer 0 0 0 2 R32f
- %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
- %s = OpVariable %_ptr_UniformConstant_10 UniformConstant
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %ii = OpVariable %_ptr_Input_int Input
-;CHECK: %uint = OpTypeInt 32 0
-;CHECK: %bool = OpTypeBool
-;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+OpCapability Shader
+OpCapability ImageBuffer
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %x %s %ii
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 450
+OpName %main "main"
+OpName %x "x"
+OpName %s "s"
+OpName %ii "ii"
+OpDecorate %x Location 11
+OpDecorate %s DescriptorSet 3
+OpDecorate %s Binding 7
+OpDecorate %s NonWritable
+OpDecorate %ii Flat
+OpDecorate %ii Location 13
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%x = OpVariable %_ptr_Output_v4float Output
+%10 = OpTypeImage %float Buffer 0 0 0 2 R32f
+%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
+%s = OpVariable %_ptr_UniformConstant_10 UniformConstant
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%ii = OpVariable %_ptr_Input_int Input
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: OpBranch %21
-;CHECK: %21 = OpLabel
-;CHECK: OpBranch %20
-;CHECK: %20 = OpLabel
-;CHECK: OpBranch %19
-;CHECK: %19 = OpLabel
- %13 = OpLoad %10 %s
- %17 = OpLoad %int %ii
- %18 = OpImageRead %v4float %13 %17
- OpStore %x %18
-;CHECK-NOT: %18 = OpImageRead %v4float %13 %17
-;CHECK-NOT: OpStore %x %18
-;CHECK: %23 = OpBitcast %uint %17
-;CHECK: %25 = OpImageQuerySize %uint %13
-;CHECK: %27 = OpULessThan %bool %23 %25
-;CHECK: OpSelectionMerge %29 None
-;CHECK: OpBranchConditional %27 %30 %31
-;CHECK: %30 = OpLabel
-;CHECK: %32 = OpLoad %10 %s
-;CHECK: %33 = OpImageRead %v4float %32 %17
-;CHECK: OpBranch %29
-;CHECK: %31 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_33 %uint_7 %uint_3 %uint_7 %uint_0 %23 %25
-;CHECK: OpBranch %29
-;CHECK: %29 = OpLabel
-;CHECK: [[phi_result:%\w+]] = OpPhi %v4float %33 %30 [[null_v4float]] %31
-;CHECK: OpStore %x [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kStreamWrite7Frag;
+%main = OpFunction %void None %3
+%5 = OpLabel
+;CHECK: OpBranch %19
+;CHECK: %19 = OpLabel
+%13 = OpLoad %10 %s
+%17 = OpLoad %int %ii
+%18 = OpImageRead %v4float %13 %17
+OpStore %x %18
+;CHECK-NOT: %18 = OpImageRead %v4float %13 %17
+;CHECK-NOT: OpStore %x %18
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_34 {{%\w+}} %uint_3 %uint_7 %uint_0 %22
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %10 %s
+;CHECK: {{%\w+}} = OpImageRead %v4float {{%\w+}} %17
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %x [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, ImageBufferOOBWrite) {
@@ -5103,85 +4685,75 @@ TEST_F(InstBindlessTest, ImageBufferOOBWrite) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability ImageBuffer
-;CHECK: OpCapability ImageQuery
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %s %ii %x
-;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %s "s"
- OpName %ii "ii"
- OpName %x "x"
- OpDecorate %s DescriptorSet 3
- OpDecorate %s Binding 7
- OpDecorate %s NonReadable
- OpDecorate %ii Flat
- OpDecorate %ii Location 13
- OpDecorate %x Location 11
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %7 = OpTypeImage %float Buffer 0 0 0 2 R32f
- %_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
- %s = OpVariable %_ptr_UniformConstant_7 UniformConstant
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %ii = OpVariable %_ptr_Input_int Input
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %x = OpVariable %_ptr_Output_v4float Output
-;CHECK: %uint = OpTypeInt 32 0
-;CHECK: %bool = OpTypeBool
-;CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint %uint
-;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: %v4uint = OpTypeVector %uint 4
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: OpBranch %21
-;CHECK: %21 = OpLabel
-;CHECK: OpBranch %20
-;CHECK: %20 = OpLabel
-;CHECK: OpBranch %19
-;CHECK: %19 = OpLabel
- %10 = OpLoad %7 %s
- %14 = OpLoad %int %ii
- %18 = OpLoad %v4float %x
- OpImageWrite %10 %14 %18
-;CHECK-NOT: OpImageWrite %10 %14 %18
-;CHECK: %23 = OpBitcast %uint %14
-;CHECK: %25 = OpImageQuerySize %uint %10
-;CHECK: %27 = OpULessThan %bool %23 %25
-;CHECK: OpSelectionMerge %29 None
-;CHECK: OpBranchConditional %27 %30 %31
-;CHECK: %30 = OpLabel
-;CHECK: %32 = OpLoad %7 %s
-;CHECK: OpImageWrite %32 %14 %18
-;CHECK: OpBranch %29
-;CHECK: %31 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_34 %uint_7 %uint_3 %uint_7 %uint_0 %23 %25
-;CHECK: OpBranch %29
-;CHECK: %29 = OpLabel
- OpReturn
- OpFunctionEnd
- )" + kStreamWrite7Frag;
+OpCapability Shader
+OpCapability ImageBuffer
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %s %ii %x
+;CHECK: OpEntryPoint Fragment %main "main" %s %ii %x %gl_FragCoord
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 450
+OpName %main "main"
+OpName %s "s"
+OpName %ii "ii"
+OpName %x "x"
+OpDecorate %s DescriptorSet 3
+OpDecorate %s Binding 7
+OpDecorate %s NonReadable
+OpDecorate %ii Flat
+OpDecorate %ii Location 13
+OpDecorate %x Location 11
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%7 = OpTypeImage %float Buffer 0 0 0 2 R32f
+%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
+%s = OpVariable %_ptr_UniformConstant_7 UniformConstant
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%ii = OpVariable %_ptr_Input_int Input
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%x = OpVariable %_ptr_Output_v4float Output
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: %19 = OpLabel
+%10 = OpLoad %7 %s
+%14 = OpLoad %int %ii
+%18 = OpLoad %v4float %x
+OpImageWrite %10 %14 %18
+;CHECK-NOT: OpImageWrite %10 %14 %18
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %7 %s
+;CHECK: OpImageWrite {{%\w+}} %14 %18
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, TextureBufferOOBFetch) {
@@ -5198,86 +4770,75 @@ TEST_F(InstBindlessTest, TextureBufferOOBFetch) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability SampledBuffer
-;CHECK: OpCapability ImageQuery
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %x %s %ii
-;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %x "x"
- OpName %s "s"
- OpName %ii "ii"
- OpDecorate %x Location 11
- OpDecorate %s DescriptorSet 3
- OpDecorate %s Binding 7
- OpDecorate %ii Flat
- OpDecorate %ii Location 13
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %x = OpVariable %_ptr_Output_v4float Output
- %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
- %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
- %s = OpVariable %_ptr_UniformConstant_10 UniformConstant
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %ii = OpVariable %_ptr_Input_int Input
-;CHECK: %uint = OpTypeInt 32 0
-;CHECK: %bool = OpTypeBool
-;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+OpCapability Shader
+OpCapability SampledBuffer
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %x %s %ii
+;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 450
+OpName %main "main"
+OpName %x "x"
+OpName %s "s"
+OpName %ii "ii"
+OpDecorate %x Location 11
+OpDecorate %s DescriptorSet 3
+OpDecorate %s Binding 7
+OpDecorate %ii Flat
+OpDecorate %ii Location 13
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%x = OpVariable %_ptr_Output_v4float Output
+%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
+%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
+%s = OpVariable %_ptr_UniformConstant_10 UniformConstant
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%ii = OpVariable %_ptr_Input_int Input
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: OpBranch %21
-;CHECK: %21 = OpLabel
-;CHECK: OpBranch %20
-;CHECK: %20 = OpLabel
-;CHECK: OpBranch %19
-;CHECK: %19 = OpLabel
- %13 = OpLoad %10 %s
- %17 = OpLoad %int %ii
- %18 = OpImageFetch %v4float %13 %17
- OpStore %x %18
-;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17
-;CHECK-NOT: OpStore %x %18
-;CHECK: %23 = OpBitcast %uint %17
-;CHECK: %25 = OpImageQuerySize %uint %13
-;CHECK: %27 = OpULessThan %bool %23 %25
-;CHECK: OpSelectionMerge %29 None
-;CHECK: OpBranchConditional %27 %30 %31
-;CHECK: %30 = OpLabel
-;CHECK: %32 = OpLoad %10 %s
-;CHECK: %33 = OpImageFetch %v4float %32 %17
-;CHECK: OpBranch %29
-;CHECK: %31 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_32 %uint_6 %uint_3 %uint_7 %uint_0 %23 %25
-;CHECK: OpBranch %29
-;CHECK: %29 = OpLabel
-;CHECK: [[phi_result:%\w+]] = OpPhi %v4float %33 %30 [[null_v4float]] %31
-;CHECK: OpStore %x [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kStreamWrite7Frag;
+%main = OpFunction %void None %3
+%5 = OpLabel
+;CHECK: OpBranch %19
+;CHECK: %19 = OpLabel
+%13 = OpLoad %10 %s
+%17 = OpLoad %int %ii
+%18 = OpImageFetch %v4float %13 %17
+OpStore %x %18
+;CHECK-NOT: %18 = OpImageFetch %v4float %13 %17
+;CHECK-NOT: OpStore %x %18
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_33 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %10 %s
+;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %17
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %x [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, SamplerBufferOOBFetch) {
@@ -5294,89 +4855,80 @@ TEST_F(InstBindlessTest, SamplerBufferOOBFetch) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability SampledBuffer
-;CHECK: OpCapability ImageQuery
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %x %s %ii
-;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %x "x"
- OpName %s "s"
- OpName %ii "ii"
- OpDecorate %x Location 11
- OpDecorate %s DescriptorSet 3
- OpDecorate %s Binding 7
- OpDecorate %ii Flat
- OpDecorate %ii Location 13
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %x = OpVariable %_ptr_Output_v4float Output
- %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
- %11 = OpTypeSampledImage %10
- %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
- %s = OpVariable %_ptr_UniformConstant_11 UniformConstant
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %ii = OpVariable %_ptr_Input_int Input
-;CHECK: %uint = OpTypeInt 32 0
-;CHECK: %bool = OpTypeBool
-;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+OpCapability Shader
+OpCapability SampledBuffer
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %x %s %ii
+;CHECK: OpEntryPoint Fragment %main "main" %x %s %ii %gl_FragCoord
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 450
+OpName %main "main"
+OpName %x "x"
+OpName %s "s"
+OpName %ii "ii"
+OpDecorate %x Location 11
+OpDecorate %s DescriptorSet 3
+OpDecorate %s Binding 7
+OpDecorate %ii Flat
+OpDecorate %ii Location 13
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%x = OpVariable %_ptr_Output_v4float Output
+%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
+%11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+%s = OpVariable %_ptr_UniformConstant_11 UniformConstant
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%ii = OpVariable %_ptr_Input_int Input
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: OpBranch %23
-;CHECK: %23 = OpLabel
-;CHECK: OpBranch %22
-;CHECK: %22 = OpLabel
-;CHECK: OpBranch %21
-;CHECK: %21 = OpLabel
- %14 = OpLoad %11 %s
- %18 = OpLoad %int %ii
- %19 = OpImage %10 %14
- %20 = OpImageFetch %v4float %19 %18
- OpStore %x %20
-;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18
-;CHECK-NOT: OpStore %x %20
-;CHECK: %25 = OpBitcast %uint %18
-;CHECK: %27 = OpImageQuerySize %uint %19
-;CHECK: %29 = OpULessThan %bool %25 %27
-;CHECK: OpSelectionMerge %31 None
-;CHECK: OpBranchConditional %29 %32 %33
-;CHECK: %32 = OpLabel
-;CHECK: %34 = OpLoad %11 %s
-;CHECK: %35 = OpImage %10 %34
-;CHECK: %36 = OpImageFetch %v4float %35 %18
-;CHECK: OpBranch %31
-;CHECK: %33 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_34 %uint_6 %uint_3 %uint_7 %uint_0 %25 %27
-;CHECK: OpBranch %31
-;CHECK: %31 = OpLabel
-;CHECK: [[phi_result:%\w+]] = OpPhi %v4float %36 %32 [[null_v4float]] %33
-;CHECK: OpStore %x [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kStreamWrite7Frag;
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+;CHECK: OpBranch %21
+;CHECK: %21 = OpLabel
+%14 = OpLoad %11 %s
+%18 = OpLoad %int %ii
+%19 = OpImage %10 %14
+%20 = OpImageFetch %v4float %19 %18
+OpStore %x %20
+;CHECK-NOT: %20 = OpImageFetch %v4float %19 %18
+;CHECK-NOT: OpStore %x %20
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_35 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %11 %s
+;CHECK: {{%\w+}} = OpImage %10 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} {{%\w+}}
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %x [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) {
@@ -5394,98 +4946,86 @@ TEST_F(InstBindlessTest, SamplerBufferConstructorOOBFetch) {
// clang-format off
const std::string text = R"(
- OpCapability Shader
- OpCapability SampledBuffer
-;CHECK: OpCapability ImageQuery
-;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
- %1 = OpExtInstImport "GLSL.std.450"
- OpMemoryModel Logical GLSL450
- OpEntryPoint Fragment %main "main" %x %tBuf %s %ii
-;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %inst_bindless_output_buffer %gl_FragCoord
- OpExecutionMode %main OriginUpperLeft
- OpSource GLSL 450
- OpName %main "main"
- OpName %x "x"
- OpName %tBuf "tBuf"
- OpName %s "s"
- OpName %ii "ii"
- OpDecorate %x Location 11
- OpDecorate %tBuf DescriptorSet 3
- OpDecorate %tBuf Binding 7
- OpDecorate %s DescriptorSet 3
- OpDecorate %s Binding 8
- OpDecorate %ii Flat
- OpDecorate %ii Location 13
-;CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
- %void = OpTypeVoid
- %3 = OpTypeFunction %void
- %float = OpTypeFloat 32
- %v4float = OpTypeVector %float 4
- %_ptr_Output_v4float = OpTypePointer Output %v4float
- %x = OpVariable %_ptr_Output_v4float Output
- %10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
- %_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
- %tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant
- %14 = OpTypeSampler
- %_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
- %s = OpVariable %_ptr_UniformConstant_14 UniformConstant
- %18 = OpTypeSampledImage %10
- %int = OpTypeInt 32 1
- %_ptr_Input_int = OpTypePointer Input %int
- %ii = OpVariable %_ptr_Input_int Input
-;CHECK: %uint = OpTypeInt 32 0
-;CHECK: %bool = OpTypeBool
-;CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-;CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
- %main = OpFunction %void None %3
- %5 = OpLabel
-;CHECK: OpBranch %28
-;CHECK: %28 = OpLabel
-;CHECK: OpBranch %27
-;CHECK: %27 = OpLabel
-;CHECK: OpBranch %26
-;CHECK: %26 = OpLabel
- %13 = OpLoad %10 %tBuf
- %17 = OpLoad %14 %s
- %19 = OpSampledImage %18 %13 %17
- %23 = OpLoad %int %ii
- %24 = OpImage %10 %19
- %25 = OpImageFetch %v4float %24 %23
- OpStore %x %25
-;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23
-;CHECK-NOT: OpStore %x %25
-;CHECK: %30 = OpBitcast %uint %23
-;CHECK: %32 = OpImageQuerySize %uint %24
-;CHECK: %34 = OpULessThan %bool %30 %32
-;CHECK: OpSelectionMerge %36 None
-;CHECK: OpBranchConditional %34 %37 %38
-;CHECK: %37 = OpLabel
-;CHECK: %39 = OpLoad %10 %tBuf
-;CHECK: %40 = OpSampledImage %18 %39 %17
-;CHECK: %41 = OpImage %10 %40
-;CHECK: %42 = OpImageFetch %v4float %41 %23
-;CHECK: OpBranch %36
-;CHECK: %38 = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_42 %uint_6 %uint_3 %uint_7 %uint_0 %30 %32
-;CHECK: OpBranch %36
-;CHECK: %36 = OpLabel
-;CHECK: [[phi_result:%\w+]] = OpPhi %v4float %42 %37 [[null_v4float]] %38
-;CHECK: OpStore %x [[phi_result]]
- OpReturn
- OpFunctionEnd
- )" + kStreamWrite7Frag;
+OpCapability Shader
+OpCapability SampledBuffer
+;CHECK: OpCapability Linkage
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main" %x %tBuf %s %ii
+;CHECK: OpEntryPoint Fragment %main "main" %x %tBuf %s %ii %gl_FragCoord
+OpExecutionMode %main OriginUpperLeft
+OpSource GLSL 450
+OpName %main "main"
+OpName %x "x"
+OpName %tBuf "tBuf"
+OpName %s "s"
+OpName %ii "ii"
+OpDecorate %x Location 11
+OpDecorate %tBuf DescriptorSet 3
+OpDecorate %tBuf Binding 7
+OpDecorate %s DescriptorSet 3
+OpDecorate %s Binding 8
+OpDecorate %ii Flat
+OpDecorate %ii Location 13
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%x = OpVariable %_ptr_Output_v4float Output
+%10 = OpTypeImage %float Buffer 0 0 0 1 Unknown
+%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
+%tBuf = OpVariable %_ptr_UniformConstant_10 UniformConstant
+%14 = OpTypeSampler
+%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
+%s = OpVariable %_ptr_UniformConstant_14 UniformConstant
+%18 = OpTypeSampledImage %10
+%int = OpTypeInt 32 1
+%_ptr_Input_int = OpTypePointer Input %int
+%ii = OpVariable %_ptr_Input_int Input
+;CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
+;CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
+;CHECK: [[null_v4float:%\w+]] = OpConstantNull %v4float
+%main = OpFunction %void None %3
+%5 = OpLabel
+%13 = OpLoad %10 %tBuf
+%17 = OpLoad %14 %s
+%19 = OpSampledImage %18 %13 %17
+%23 = OpLoad %int %ii
+%24 = OpImage %10 %19
+%25 = OpImageFetch %v4float %24 %23
+OpStore %x %25
+;CHECK-NOT: %25 = OpImageFetch %v4float %24 %23
+;CHECK-NOT: OpStore %x %25
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_43 {{%\w+}} %uint_3 %uint_7 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %10 %tBuf
+;CHECK: {{%\w+}} = OpSampledImage %18 {{%\w+}} %17
+;CHECK: {{%\w+}} = OpImage %10 {{%\w+}}
+;CHECK: {{%\w+}} = OpImageFetch %v4float {{%\w+}} %23
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v4float {{%\w+}} {{%\w+}} [[null_v4float]] {{%\w+}}
+;CHECK: OpStore %x [[phi_result]]
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false,
- false, true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
TEST_F(InstBindlessTest, DeviceBufferAddressOOB) {
@@ -5509,11 +5049,13 @@ TEST_F(InstBindlessTest, DeviceBufferAddressOOB) {
const std::string text = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
+;CHECK: OpCapability Linkage
;CHECK: OpCapability Int64
+OpExtension "SPV_KHR_physical_storage_buffer"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Vertex %main "main" %u_info
-;CHECK: OpEntryPoint Vertex %main "main" %u_info %inst_bindless_input_buffer %inst_bindless_output_buffer %gl_VertexIndex %gl_InstanceIndex
+;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex
OpSource GLSL 450
OpSourceExtension "GL_EXT_buffer_reference"
OpName %main "main"
@@ -5531,9 +5073,8 @@ OpDecorate %_arr_int_uint_4 ArrayStride 16
OpMemberDecorate %bufStruct 0 Offset 0
OpDecorate %bufStruct Block
OpDecorate %u_info DescriptorSet 0
-OpDecorate %u_info Binding 0)"
- + kInputDecorations + kOutputDecorations +
-R"(%void = OpTypeVoid
+OpDecorate %u_info Binding 0
+%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
%_ptr_Function_int = OpTypePointer Function %int
@@ -5552,18 +5093,11 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%bool = OpTypeBool
%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
%int_n559035791 = OpConstant %int -559035791
-%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int)"
- + kInputGlobals + kOutputGlobals +
-R"(%main = OpFunction %void None %3
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
%5 = OpLabel
%i = OpVariable %_ptr_Function_int Function
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: [[desc_state:%\w+]] = OpFunctionCall %uint %inst_bindless_read_desc_init %uint_0 %uint_0 %uint_0
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
-;CHECK: OpBranch {{%\w+}}
-;CHECK: {{%\w+}} = OpLabel
OpStore %i %int_0
OpBranch %10
%10 = OpLabel
@@ -5572,37 +5106,41 @@ OpBranch %14
%14 = OpLabel
%15 = OpLoad %int %i
%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1
-%27 = OpLoad %int %26
-%29 = OpSLessThan %bool %15 %27
-;CHECK-NOT: %27 = OpLoad %int %26
-;CHECK-NOT: %29 = OpSLessThan %bool %15 %27
;CHECK: {{%\w+}} = OpIAdd %uint %uint_8 %uint_3
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_56 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[load_result:%\w+]] = OpLoad %int %26
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_54 %uint_4 %uint_0 %uint_0 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[phi_result:%\w+]] = OpPhi %int [[load_result]] {{%\w+}} {{%\w+}} {{%\w+}}
-;CHECK: {{%\w+}} = OpSLessThan %bool %15 [[phi_result]]
+%27 = OpLoad %int %26
+%29 = OpSLessThan %bool %15 %27
+;CHECK-NOT: %27 = OpLoad %int %26
+;CHECK-NOT: %29 = OpSLessThan %bool %15 %27
+;CHECK: %29 = OpSLessThan %bool %15 [[phi_result]]
OpBranchConditional %29 %11 %12
%11 = OpLabel
%31 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
%32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31
;CHECK-NOT: %32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31
;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 %uint_7
-;CHECK: {{%\w+}} = OpULessThan %bool {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_61 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
;CHECK: OpSelectionMerge {{%\w+}} None
;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
;CHECK: [[load_result_2:%\w+]] = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
-;CHECK: {{%\w+}} = OpFunctionCall %void %inst_bindless_stream_write_7 %uint_59 %uint_4 %uint_0 %uint_0 %uint_0 {{%\w+}} {{%\w+}}
;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_bufStruct {{%\w+}}
;CHECK: OpBranch {{%\w+}}
;CHECK: {{%\w+}} = OpLabel
@@ -5620,14 +5158,144 @@ OpStore %i %38
OpBranch %10
%12 = OpLabel
OpReturn
-OpFunctionEnd)"
- + kReadDescInit + kStreamWrite7Vert;
+OpFunctionEnd)";
+ // clang-format on
+
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
+}
+
+TEST_F(InstBindlessTest, VertexIndexOOB) {
+ // #version 450
+ // layout(std140, binding = 0) uniform foo { uint tex_index[1]; }
+ // uniform_index_buffer; layout(location = 0) out flat uint index; vec2
+ // vertices[3]; void main() {
+ // vertices[0] = vec2(-1.0, -1.0);
+ // vertices[1] = vec2( 1.0, -1.0);
+ // vertices[2] = vec2( 0.0, 1.0);
+ // gl_Position = vec4(vertices[gl_VertexIndex % 3], 0.0, 1.0);
+ // index = uniform_index_buffer.tex_index[0];
+ // }
+ // clang-format off
+ const std::string text = R"(
+OpCapability Shader
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint Vertex %main "main" %vertices %_ %gl_VertexIndex %index %uniform_index_buffer
+OpSource GLSL 450
+OpName %main "main"
+OpName %vertices "vertices"
+OpName %gl_PerVertex "gl_PerVertex"
+OpMemberName %gl_PerVertex 0 "gl_Position"
+OpMemberName %gl_PerVertex 1 "gl_PointSize"
+OpMemberName %gl_PerVertex 2 "gl_ClipDistance"
+OpMemberName %gl_PerVertex 3 "gl_CullDistance"
+OpName %_ ""
+OpName %gl_VertexIndex "gl_VertexIndex"
+OpName %index "index"
+OpName %foo "foo"
+OpMemberName %foo 0 "tex_index"
+OpName %uniform_index_buffer "uniform_index_buffer"
+OpMemberDecorate %gl_PerVertex 0 BuiltIn Position
+OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
+OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance
+OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance
+OpDecorate %gl_PerVertex Block
+OpDecorate %gl_VertexIndex BuiltIn VertexIndex
+OpDecorate %index Flat
+OpDecorate %index Location 0
+OpDecorate %_arr_uint_uint_1 ArrayStride 16
+OpMemberDecorate %foo 0 Offset 0
+OpDecorate %foo Block
+OpDecorate %uniform_index_buffer DescriptorSet 0
+OpDecorate %uniform_index_buffer Binding 0
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%float = OpTypeFloat 32
+%v2float = OpTypeVector %float 2
+%uint = OpTypeInt 32 0
+%uint_3 = OpConstant %uint 3
+%_arr_v2float_uint_3 = OpTypeArray %v2float %uint_3
+%_ptr_Private__arr_v2float_uint_3 = OpTypePointer Private %_arr_v2float_uint_3
+%vertices = OpVariable %_ptr_Private__arr_v2float_uint_3 Private
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%float_n1 = OpConstant %float -1
+%16 = OpConstantComposite %v2float %float_n1 %float_n1
+%_ptr_Private_v2float = OpTypePointer Private %v2float
+%int_1 = OpConstant %int 1
+%float_1 = OpConstant %float 1
+%21 = OpConstantComposite %v2float %float_1 %float_n1
+%int_2 = OpConstant %int 2
+%float_0 = OpConstant %float 0
+%25 = OpConstantComposite %v2float %float_0 %float_1
+%v4float = OpTypeVector %float 4
+%uint_1 = OpConstant %uint 1
+%_arr_float_uint_1 = OpTypeArray %float %uint_1
+%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
+%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex
+%_ = OpVariable %_ptr_Output_gl_PerVertex Output
+%_ptr_Input_int = OpTypePointer Input %int
+%gl_VertexIndex = OpVariable %_ptr_Input_int Input
+%int_3 = OpConstant %int 3
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+%_ptr_Output_uint = OpTypePointer Output %uint
+%index = OpVariable %_ptr_Output_uint Output
+%_arr_uint_uint_1 = OpTypeArray %uint %uint_1
+%foo = OpTypeStruct %_arr_uint_uint_1
+%_ptr_Uniform_foo = OpTypePointer Uniform %foo
+%uniform_index_buffer = OpVariable %_ptr_Uniform_foo Uniform
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+)" + kImportStub + R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+%18 = OpAccessChain %_ptr_Private_v2float %vertices %int_0
+OpStore %18 %16
+%22 = OpAccessChain %_ptr_Private_v2float %vertices %int_1
+OpStore %22 %21
+%26 = OpAccessChain %_ptr_Private_v2float %vertices %int_2
+OpStore %26 %25
+%35 = OpLoad %int %gl_VertexIndex
+%37 = OpSMod %int %35 %int_3
+%38 = OpAccessChain %_ptr_Private_v2float %vertices %37
+%39 = OpLoad %v2float %38
+%40 = OpCompositeExtract %float %39 0
+%41 = OpCompositeExtract %float %39 1
+%42 = OpCompositeConstruct %v4float %40 %41 %float_0 %float_1
+%44 = OpAccessChain %_ptr_Output_v4float %_ %int_0
+OpStore %44 %42
+%52 = OpAccessChain %_ptr_Uniform_uint %uniform_index_buffer %int_0 %int_0
+%53 = OpLoad %uint %52
+;CHECK-NOT: %53 = OpLoad %uint %52
+;CHECK: {{%\w+}} = OpIMul %uint %uint_16 %int_0
+;CHECK: {{%\w+}} = OpIAdd %uint %uint_0 {{%\w+}}
+;CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
+;CHECK: {{%\w+}} = OpLoad %int %gl_VertexIndex
+;CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_87 {{%\w+}} %uint_0 %uint_0 %uint_0 {{%\w+}}
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %uint %52
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %index [[phi_result]]
+OpStore %index %53
+;CHECK-NOT: OpStore %index %53
+OpReturn
+;CHECK: OpReturn
+OpFunctionEnd)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 7u, 23u, false, true,
- true, true, true);
+ SinglePassRunAndMatch<InstBindlessCheckPass>(text, true, 23u);
}
// TODO(greg-lunarg): Add tests to verify handling of these cases:
diff --git a/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
index 80e6b7a06..72d343852 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_buff_addr_check_test.cpp
@@ -26,161 +26,14 @@ namespace spvtools {
namespace opt {
namespace {
-static const std::string kOutputDecorations = R"(
-; CHECK: OpDecorate [[output_buffer_type:%inst_buff_addr_OutputBuffer]] Block
-; CHECK: OpMemberDecorate [[output_buffer_type]] 0 Offset 0
-; CHECK: OpMemberDecorate [[output_buffer_type]] 1 Offset 4
-; CHECK: OpDecorate [[output_buffer_var:%\w+]] DescriptorSet 7
-; CHECK: OpDecorate [[output_buffer_var]] Binding 0
+static const std::string kFuncName = "inst_buff_addr_search_and_test";
+static const std::string kImportDeco = R"(
+;CHECK: OpDecorate %)" + kFuncName + R"( LinkageAttributes ")" +
+ kFuncName + R"(" Import
)";
-
-static const std::string kOutputGlobals = R"(
-; CHECK: [[output_buffer_type]] = OpTypeStruct %uint %uint %_runtimearr_uint
-; CHECK: [[output_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[output_buffer_type]]
-; CHECK: [[output_buffer_var]] = OpVariable [[output_ptr_type]] StorageBuffer
-)";
-
-static const std::string kStreamWrite4Begin = R"(
-; CHECK: {{%\w+}} = OpFunction %void None {{%\w+}}
-; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1
-; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_10
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10
-; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 2
-; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
-; CHECK: OpSelectionMerge {{%\w+}} None
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_10
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_23
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_1]]
-)";
-
-static const std::string kStreamWrite4End = R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_2]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_3]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_4]]
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpReturn
-; CHECK: OpFunctionEnd
-)";
-
-// clang-format off
-static const std::string kStreamWrite4Frag = kStreamWrite4Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
-; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite4End;
-
-static const std::string kStreamWrite4Compute = kStreamWrite4Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite4End;
-// clang-format on
-
-// clang-format off
-static const std::string kStreamWrite4Vert = kStreamWrite4Begin + R"(
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-)" + kStreamWrite4End;
-// clang-format on
-
-static const std::string kInputDecorations = R"(
-; CHECK: OpDecorate [[input_buffer_type:%inst_buff_addr_InputBuffer]] Block
-; CHECK: OpMemberDecorate [[input_buffer_type]] 0 Offset 0
-; CHECK: OpDecorate [[input_buffer_var:%\w+]] DescriptorSet 7
-; CHECK: OpDecorate [[input_buffer_var]] Binding 2
-)";
-
-static const std::string kInputGlobals = R"(
-; CHECK: [[input_buffer_type]] = OpTypeStruct %_runtimearr_ulong
-; CHECK: [[input_ptr_type:%\w+]] = OpTypePointer StorageBuffer [[input_buffer_type]]
-; CHECK: [[input_buffer_var]] = OpVariable [[input_ptr_type]] StorageBuffer
-)";
-
-static const std::string kSearchAndTest = R"(
-; CHECK: {{%\w+}} = OpFunction %bool None {{%\w+}}
-; CHECK: [[param_1:%\w+]] = OpFunctionParameter %ulong
-; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpPhi %uint %uint_1 {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: OpLoopMerge {{%\w+}} {{%\w+}} None
-; CHECK: OpBranch {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}}
-; CHECK: {{%\w+}} = OpUGreaterThan %bool {{%\w+}} [[param_1]]
-; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpISub %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}}
-; CHECK: {{%\w+}} = OpISub %ulong [[param_1]] {{%\w+}}
-; CHECK: {{%\w+}} = OpUConvert %ulong [[param_2]]
-; CHECK: {{%\w+}} = OpIAdd %ulong {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 %uint_0
-; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}}
-; CHECK: {{%\w+}} = OpUConvert %uint {{%\w+}}
-; CHECK: {{%\w+}} = OpISub %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_ulong [[input_buffer_var]] %uint_0 {{%\w+}}
-; CHECK: {{%\w+}} = OpLoad %ulong {{%\w+}}
-; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
-; CHECK: OpReturnValue {{%\w+}}
-; CHECK: OpFunctionEnd
+static const std::string kImportStub = R"(
+;CHECK: %)" + kFuncName + R"( = OpFunction %bool None {{%\w+}}
+;CHECK: OpFunctionEnd
)";
// clang-format on
@@ -209,13 +62,13 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferStore) {
const std::string defs = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
-; CHECK: OpCapability Int64
+;CHECK: OpCapability Int64
OpExtension "SPV_EXT_physical_storage_buffer"
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint GLCompute %main "main"
-; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
OpSourceExtension "GL_EXT_buffer_reference"
@@ -240,11 +93,8 @@ OpMemberDecorate %bufStruct 1 Offset 32
OpDecorate %bufStruct Block
OpDecorate %u_info DescriptorSet 0
OpDecorate %u_info Binding 0
-; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
)";
const std::string globals = R"(
@@ -265,19 +115,11 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%int_1 = OpConstant %int 1
%int_3239 = OpConstant %int 3239
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
-; CHECK: %ulong = OpTypeInt 64 0
-; CHECK: %bool = OpTypeBool
-; CHECK: %28 = OpTypeFunction %bool %ulong %uint
-; CHECK: %_runtimearr_ulong = OpTypeRuntimeArray %ulong
-)" + kInputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_ulong = OpTypePointer StorageBuffer %ulong
-; CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint
-; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
-)" + kOutputGlobals + R"(
-; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
-; CHECK: %v3uint = OpTypeVector %uint 3
-; CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint
-; CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
+;CHECK: %ulong = OpTypeInt 64 0
+;CHECK: %bool = OpTypeBool
+;CHECK: %v3uint = OpTypeVector %uint 3
+;CHECK: %_ptr_Input_v3uint = OpTypePointer Input %v3uint
+;CHECK: %gl_GlobalInvocationID = OpVariable %_ptr_Input_v3uint Input
)";
// clang-format off
@@ -287,36 +129,35 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
-; CHECK-NOT: %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
-; CHECK-NOT: %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
-; CHECK-NOT: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
-; CHECK: %20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
-; CHECK: %21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20
-; CHECK: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1
-; CHECK: %24 = OpConvertPtrToU %ulong %22
-; CHECK: %61 = OpFunctionCall %bool %inst_buff_addr_search_and_test %24 %uint_4
-; CHECK: OpSelectionMerge %62 None
-; CHECK: OpBranchConditional %61 %63 %64
-; CHECK: %63 = OpLabel
+;CHECK-NOT: %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
+;CHECK-NOT: %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
+;CHECK-NOT: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
+;CHECK: %20 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
+;CHECK: %21 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %20
+;CHECK: %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %21 %int_1
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %22
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_49 {{%\w+}} {{%\w+}} %uint_4
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpStore %22 %int_3239 Aligned 16
-; CHECK: OpStore %22 %int_3239 Aligned 16
-; CHECK: OpBranch %62
-; CHECK: %64 = OpLabel
-; CHECK: %65 = OpUConvert %uint %24
-; CHECK: %67 = OpShiftRightLogical %ulong %24 %uint_32
-; CHECK: %68 = OpUConvert %uint %67
-; CHECK: %124 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_48 %uint_2 %65 %68
-; CHECK: OpBranch %62
-; CHECK: %62 = OpLabel
+;CHECK: OpStore %22 %int_3239 Aligned 16
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
- const std::string output_funcs = kSearchAndTest + kStreamWrite4Compute;
-
// SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<InstBuffAddrCheckPass>(
- defs + decorates + globals + main_func + output_funcs, true, 7u, 23u);
+ defs + decorates + globals + kImportStub + main_func, true, 23u);
}
TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) {
@@ -346,7 +187,7 @@ TEST_F(InstBuffAddrTest, InstPhysicalStorageBufferLoadAndStore) {
const std::string defs = R"(
OpCapability Shader
OpCapability PhysicalStorageBufferAddresses
-; CHECK: OpCapability Int64
+;CHECK: OpCapability Int64
OpExtension "SPV_EXT_physical_storage_buffer"
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
@@ -356,7 +197,7 @@ OpExecutionMode %main LocalSize 1 1 1
OpSource GLSL 450
OpSourceExtension "GL_EXT_buffer_reference"
OpName %main "main"
-; CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
+;CHECK: OpEntryPoint GLCompute %main "main" %gl_GlobalInvocationID
OpName %blockType "blockType"
OpMemberName %blockType 0 "x"
OpMemberName %blockType 1 "next"
@@ -374,13 +215,9 @@ OpMemberDecorate %rootBlock 0 Offset 0
OpDecorate %rootBlock Block
OpDecorate %r DescriptorSet 0
OpDecorate %r Binding 0
-; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_GlobalInvocationID BuiltIn GlobalInvocationId
)";
- // clang-format on
const std::string globals = R"(
%void = OpTypeVoid
@@ -398,7 +235,7 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%_ptr_PhysicalStorageBuffer__ptr_PhysicalStorageBuffer_blockType = OpTypePointer PhysicalStorageBuffer %_ptr_PhysicalStorageBuffer_blockType
%int_531 = OpConstant %int 531
%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
-)" + kInputGlobals + kOutputGlobals;
+)";
const std::string main_func = R"(
%main = OpFunction %void None %3
@@ -409,48 +246,49 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_blockType PhysicalStorageBuffer
%22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
%26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
OpStore %26 %int_531 Aligned 16
-; CHECK-NOT: %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
-; CHECK-NOT: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
-; CHECK: %30 = OpConvertPtrToU %ulong %21
-; CHECK: %67 = OpFunctionCall %bool %inst_buff_addr_search_and_test %30 %uint_8
-; CHECK: OpSelectionMerge %68 None
-; CHECK: OpBranchConditional %67 %69 %70
-; CHECK: %69 = OpLabel
-; CHECK: %71 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
-; CHECK: OpBranch %68
-; CHECK: %70 = OpLabel
-; CHECK: %72 = OpUConvert %uint %30
-; CHECK: %74 = OpShiftRightLogical %ulong %30 %uint_32
-; CHECK: %75 = OpUConvert %uint %74
-; CHECK: %131 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_44 %uint_2 %72 %75
-; CHECK: %133 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_blockType %132
-; CHECK: OpBranch %68
-; CHECK: %68 = OpLabel
-; CHECK: %134 = OpPhi %_ptr_PhysicalStorageBuffer_blockType %71 %69 %133 %70
-; CHECK: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %134 %int_0
-; CHECK: %135 = OpConvertPtrToU %ulong %26
-; CHECK: %136 = OpFunctionCall %bool %inst_buff_addr_search_and_test %135 %uint_4
-; CHECK: OpSelectionMerge %137 None
-; CHECK: OpBranchConditional %136 %138 %139
-; CHECK: %138 = OpLabel
-; CHECK: OpStore %26 %int_531 Aligned 16
-; CHECK: OpBranch %137
-; CHECK: %139 = OpLabel
-; CHECK: %140 = OpUConvert %uint %135
-; CHECK: %141 = OpShiftRightLogical %ulong %135 %uint_32
-; CHECK: %142 = OpUConvert %uint %141
-; CHECK: %144 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_46 %uint_2 %140 %142
-; CHECK: OpBranch %137
-; CHECK: %137 = OpLabel
+;CHECK-NOT: %22 = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
+;CHECK-NOT: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %22 %int_0
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %21
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_45 {{%\w+}} {{%\w+}} %uint_8
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %_ptr_PhysicalStorageBuffer_blockType %21 Aligned 8
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_blockType %52
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpPhi %_ptr_PhysicalStorageBuffer_blockType {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: %26 = OpAccessChain %_ptr_PhysicalStorageBuffer_int {{%\w+}} %int_0
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %26
+;CHECK: {{%\w+}} = OpLoad %v3uint %gl_GlobalInvocationID
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 2
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_5 {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_47 {{%\w+}} {{%\w+}} %uint_4
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %26 %int_531 Aligned 16
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpReturn
OpFunctionEnd
)";
-
- const std::string output_funcs = kSearchAndTest + kStreamWrite4Compute;
+ // clang-format on
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<InstBuffAddrCheckPass>(
- defs + decorates + globals + main_func + output_funcs, true, 7u, 23u);
+ defs + decorates + globals + kImportStub + main_func, true, 23u);
}
TEST_F(InstBuffAddrTest, StructLoad) {
@@ -477,11 +315,11 @@ TEST_F(InstBuffAddrTest, StructLoad) {
OpCapability Shader
OpCapability Int64
OpCapability PhysicalStorageBufferAddresses
-; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
+;CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Fragment %main "main"
-; CHECK: OpEntryPoint Fragment %main "main" %inst_buff_addr_input_buffer %inst_buff_addr_output_buffer %gl_FragCoord
+;CHECK: OpEntryPoint Fragment %main "main" %gl_FragCoord
OpExecutionMode %main OriginUpperLeft
OpSource GLSL 450
OpSourceExtension "GL_ARB_gpu_shader_int64"
@@ -500,11 +338,8 @@ OpMemberName %TestBuffer 0 "test"
OpMemberDecorate %Test_0 0 Offset 0
OpMemberDecorate %TestBuffer 0 Offset 0
OpDecorate %TestBuffer Block
-; CHECK: OpDecorate %_runtimearr_ulong ArrayStride 8
-)" + kInputDecorations + R"(
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
)";
const std::string globals = R"(
@@ -521,50 +356,176 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffe
%int_0 = OpConstant %int 0
%_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0
%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704
-; CHECK: %47 = OpTypeFunction %bool %ulong %uint
-)" + kInputGlobals + R"(
-; CHECK: {{%\w+}} = OpTypeFunction %void %uint %uint %uint %uint
-)" + kOutputGlobals + R"(
-; CHECK: %143 = OpConstantNull %Test_0
+;CHECK: {{%\w+}} = OpConstantNull %Test_0
)";
- // clang-format on
- const std::string main_func =
- R"(
+ const std::string main_func = R"(
%main = OpFunction %void None %3
%5 = OpLabel
%37 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %ulong_18446744073172680704
%38 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %37 %int_0
%39 = OpLoad %Test_0 %38 Aligned 16
-; CHECK-NOT: %39 = OpLoad %Test_0 %38 Aligned 16
-; CHECK: %43 = OpConvertPtrToU %ulong %38
-; CHECK: %80 = OpFunctionCall %bool %inst_buff_addr_search_and_test %43 %uint_4
-; CHECK: OpSelectionMerge %81 None
-; CHECK: OpBranchConditional %80 %82 %83
-; CHECK: %82 = OpLabel
-; CHECK: %84 = OpLoad %Test_0 %38 Aligned 16
-; CHECK: OpBranch %81
-; CHECK: %83 = OpLabel
-; CHECK: %85 = OpUConvert %uint %43
-; CHECK: %87 = OpShiftRightLogical %ulong %43 %uint_32
-; CHECK: %88 = OpUConvert %uint %87
-; CHECK: %142 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_37 %uint_2 %85 %88
-; CHECK: OpBranch %81
-; CHECK: %81 = OpLabel
-; CHECK: %144 = OpPhi %Test_0 %84 %82 %143 %83
+;CHECK-NOT: %39 = OpLoad %Test_0 %38 Aligned 16
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %38
+;CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
+;CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+;CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_4 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_38 {{%\w+}} {{%\w+}} %uint_4
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %Test_0 %38 Aligned 16
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
%40 = OpCopyLogical %Test %39
-; CHECK-NOT: %40 = OpCopyLogical %Test %39
-; CHECK: %40 = OpCopyLogical %Test %144
+;CHECK-NOT: %40 = OpCopyLogical %Test %39
+;CHECK: %40 = OpCopyLogical %Test [[phi_result]]
OpReturn
OpFunctionEnd
)";
+ // clang-format on
+
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<InstBuffAddrCheckPass>(
+ defs + decorates + globals + kImportStub + main_func, true);
+}
+
+TEST_F(InstBuffAddrTest, PaddedStructLoad) {
+ // #version 450
+ // #extension GL_EXT_buffer_reference : enable
+ // #extension GL_ARB_gpu_shader_int64 : enable
+ // struct Test {
+ // uvec3 pad_1; // Offset 0 Size 12
+ // double pad_2; // Offset 16 Size 8 (alignment requirement)
+ // float a; // Offset 24 Size 4
+ // }; // Total Size 28
+ //
+ // layout(buffer_reference, std430, buffer_reference_align = 16) buffer
+ // TestBuffer { Test test; };
+ //
+ // Test GetTest(uint64_t ptr) {
+ // return TestBuffer(ptr).test;
+ // }
+ //
+ // void main() {
+ // GetTest(0xe0000000);
+ // }
+
+ const std::string defs =
+ R"(
+OpCapability Shader
+OpCapability Float64
+OpCapability Int64
+OpCapability PhysicalStorageBufferAddresses
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint Vertex %main "main"
+OpSource GLSL 450
+OpSourceExtension "GL_ARB_gpu_shader_int64"
+OpSourceExtension "GL_EXT_buffer_reference"
+OpName %main "main"
+OpName %Test "Test"
+OpMemberName %Test 0 "pad_1"
+OpMemberName %Test 1 "pad_2"
+OpMemberName %Test 2 "a"
+OpName %GetTest_u641_ "GetTest(u641;"
+OpName %ptr "ptr"
+OpName %Test_0 "Test"
+OpMemberName %Test_0 0 "pad_1"
+OpMemberName %Test_0 1 "pad_2"
+OpMemberName %Test_0 2 "a"
+OpName %TestBuffer "TestBuffer"
+OpMemberName %TestBuffer 0 "test"
+OpName %param "param"
+)";
- const std::string output_funcs = kSearchAndTest + kStreamWrite4Frag;
+ // clang-format off
+ const std::string decorates = R"(
+OpDecorate %TestBuffer Block
+OpMemberDecorate %Test_0 0 Offset 0
+OpMemberDecorate %Test_0 1 Offset 16
+OpMemberDecorate %Test_0 2 Offset 24
+OpMemberDecorate %TestBuffer 0 Offset 0
+)" + kImportDeco + R"(
+;CHECK: OpDecorate %gl_VertexIndex BuiltIn VertexIndex
+;CHECK: OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
+)";
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ const std::string globals = R"(
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%ulong = OpTypeInt 64 0
+%_ptr_Function_ulong = OpTypePointer Function %ulong
+%uint = OpTypeInt 32 0
+%v3uint = OpTypeVector %uint 3
+%double = OpTypeFloat 64
+%float = OpTypeFloat 32
+%Test = OpTypeStruct %v3uint %double %float
+%13 = OpTypeFunction %Test %_ptr_Function_ulong
+OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_TestBuffer PhysicalStorageBuffer
+%Test_0 = OpTypeStruct %v3uint %double %float
+%TestBuffer = OpTypeStruct %Test_0
+%_ptr_PhysicalStorageBuffer_TestBuffer = OpTypePointer PhysicalStorageBuffer %TestBuffer
+%int = OpTypeInt 32 1
+%int_0 = OpConstant %int 0
+%_ptr_PhysicalStorageBuffer_Test_0 = OpTypePointer PhysicalStorageBuffer %Test_0
+%_ptr_Function_Test = OpTypePointer Function %Test
+%ulong_18446744073172680704 = OpConstant %ulong 18446744073172680704
+;CHECK: {{%\w+}} = OpConstantNull %Test_0
+)";
+
+ const std::string main_func = R"(
+%main = OpFunction %void None %3
+%5 = OpLabel
+%param = OpVariable %_ptr_Function_ulong Function
+OpStore %param %ulong_18446744073172680704
+%35 = OpFunctionCall %Test %GetTest_u641_ %param
+OpReturn
+OpFunctionEnd
+%GetTest_u641_ = OpFunction %Test None %13
+%ptr = OpFunctionParameter %_ptr_Function_ulong
+%16 = OpLabel
+%28 = OpVariable %_ptr_Function_Test Function
+%17 = OpLoad %ulong %ptr
+%21 = OpConvertUToPtr %_ptr_PhysicalStorageBuffer_TestBuffer %17
+%25 = OpAccessChain %_ptr_PhysicalStorageBuffer_Test_0 %21 %int_0
+%26 = OpLoad %Test_0 %25 Aligned 16
+%29 = OpCopyLogical %Test %26
+;CHECK-NOT: %30 = OpLoad %Test %28
+;CHECK-NOT: %26 = OpLoad %Test_0 %25 Aligned 16
+;CHECK-NOT: %29 = OpCopyLogical %Test %26
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %25
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_28
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %Test_0 %25 Aligned 16
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %Test_0 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: %29 = OpCopyLogical %Test [[phi_result]]
+OpStore %28 %29
+%30 = OpLoad %Test %28
+OpReturnValue %30
+OpFunctionEnd
+)";
+ // clang-format on
+
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
SinglePassRunAndMatch<InstBuffAddrCheckPass>(
- defs + decorates + globals + main_func + output_funcs, true);
+ defs + decorates + globals + kImportStub + main_func, true);
}
TEST_F(InstBuffAddrTest, DeviceBufferAddressOOB) {
@@ -591,7 +552,7 @@ OpCapability PhysicalStorageBufferAddresses
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel PhysicalStorageBuffer64 GLSL450
OpEntryPoint Vertex %main "main" %u_info
-;CHECK: OpEntryPoint Vertex %main "main" %u_info %inst_buff_addr_input_buffer %inst_buff_addr_output_buffer %gl_VertexIndex %gl_InstanceIndex
+;CHECK: OpEntryPoint Vertex %main "main" %u_info %gl_VertexIndex %gl_InstanceIndex
OpSource GLSL 450
OpSourceExtension "GL_EXT_buffer_reference"
OpName %main "main"
@@ -609,7 +570,8 @@ OpDecorate %_arr_int_uint_4 ArrayStride 16
OpMemberDecorate %bufStruct 0 Offset 0
OpDecorate %bufStruct Block
OpDecorate %u_info DescriptorSet 0
-OpDecorate %u_info Binding 0)" + kInputDecorations + kOutputDecorations + R"(
+OpDecorate %u_info Binding 0
+)" + kImportDeco + R"(
%void = OpTypeVoid
%3 = OpTypeFunction %void
%int = OpTypeInt 32 1
@@ -629,7 +591,8 @@ OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
%bool = OpTypeBool
%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
%int_n559035791 = OpConstant %int -559035791
-%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int)" + kInputGlobals + kOutputGlobals + R"(
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+)" + kImportStub + R"(
%main = OpFunction %void None %3
%5 = OpLabel
%i = OpVariable %_ptr_Function_int Function
@@ -649,20 +612,20 @@ OpBranchConditional %29 %11 %12
%32 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %31
%33 = OpLoad %int %i
%36 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %32 %int_0 %33
-;CHECK: %41 = OpConvertPtrToU %ulong %36
-;CHECK: %76 = OpFunctionCall %bool %inst_buff_addr_search_and_test %41 %uint_4
-;CHECK: OpSelectionMerge %77 None
-;CHECK: OpBranchConditional %76 %78 %79
-;CHECK: %78 = OpLabel
OpStore %36 %int_n559035791 Aligned 16
-;CHECK: OpBranch %77
-;CHECK: 79 = OpLabel
-;CHECK: 80 = OpUConvert %uint %41
-;CHECK: 82 = OpShiftRightLogical %ulong %41 %uint_32
-;CHECK: 83 = OpUConvert %uint %82
-;CHECK: 134 = OpFunctionCall %void %inst_buff_addr_stream_write_4 %uint_62 %uint_2 %80 %83
-;CHECK: OpBranch %77
-;CHECK: 77 = OpLabel
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %36
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: {{%\w+}} = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_63 {{%\w+}} {{%\w+}} %uint_4
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpStore %36 %int_n559035791 Aligned 16
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
OpBranch %13
%13 = OpLabel
%37 = OpLoad %int %i
@@ -671,12 +634,137 @@ OpStore %i %38
OpBranch %10
%12 = OpLabel
OpReturn
-OpFunctionEnd)" + kSearchAndTest + kStreamWrite4Vert;
+OpFunctionEnd)";
+ // clang-format on
+
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
+ SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ SinglePassRunAndMatch<InstBuffAddrCheckPass>(text, true, 23);
+}
+
+TEST_F(InstBuffAddrTest, UVec3ScalarAddressOOB) {
+ // clang-format off
+ // #version 450
+ // #extension GL_EXT_buffer_reference : enable
+ // #extension GL_EXT_scalar_block_layout : enable
+ // layout(buffer_reference, std430, scalar) readonly buffer IndexBuffer
+ // {
+ // uvec3 indices[];
+ // };
+ // layout(set = 0, binding = 0) uniform ufoo {
+ // IndexBuffer data;
+ // int nReads;
+ // } u_info;
+ // void main() {
+ // uvec3 readvec;
+ // for (int i=0; i < u_info.nReads; ++i) {
+ // readvec = u_info.data.indices[i];
+ // }
+ // }
+ const std::string text = R"(
+OpCapability Shader
+OpCapability PhysicalStorageBufferAddresses
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint Vertex %main "main" %u_info
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_buffer_reference"
+OpSourceExtension "GL_EXT_scalar_block_layout"
+OpName %main "main"
+OpName %i "i"
+OpName %ufoo "ufoo"
+OpMemberName %ufoo 0 "data"
+OpMemberName %ufoo 1 "nReads"
+OpName %IndexBuffer "IndexBuffer"
+OpMemberName %IndexBuffer 0 "indices"
+OpName %u_info "u_info"
+OpName %readvec "readvec"
+OpMemberDecorate %ufoo 0 Offset 0
+OpMemberDecorate %ufoo 1 Offset 8
+OpDecorate %ufoo Block
+OpDecorate %_runtimearr_v3uint ArrayStride 12
+OpMemberDecorate %IndexBuffer 0 NonWritable
+OpMemberDecorate %IndexBuffer 0 Offset 0
+OpDecorate %IndexBuffer Block
+OpDecorate %u_info DescriptorSet 0
+OpDecorate %u_info Binding 0
+)" + kImportDeco + R"(
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%_ptr_Function_int = OpTypePointer Function %int
+%int_0 = OpConstant %int 0
+OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_IndexBuffer PhysicalStorageBuffer
+%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_IndexBuffer %int
+%uint = OpTypeInt 32 0
+%v3uint = OpTypeVector %uint 3
+%_runtimearr_v3uint = OpTypeRuntimeArray %v3uint
+%IndexBuffer = OpTypeStruct %_runtimearr_v3uint
+%_ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer PhysicalStorageBuffer %IndexBuffer
+%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
+%u_info = OpVariable %_ptr_Uniform_ufoo Uniform
+%int_1 = OpConstant %int 1
+%_ptr_Uniform_int = OpTypePointer Uniform %int
+%bool = OpTypeBool
+)" + kImportStub + R"(
+%_ptr_Function_v3uint = OpTypePointer Function %v3uint
+%_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_IndexBuffer
+%_ptr_PhysicalStorageBuffer_v3uint = OpTypePointer PhysicalStorageBuffer %v3uint
+%main = OpFunction %void None %3
+%5 = OpLabel
+%i = OpVariable %_ptr_Function_int Function
+%readvec = OpVariable %_ptr_Function_v3uint Function
+OpStore %i %int_0
+OpBranch %10
+%10 = OpLabel
+OpLoopMerge %12 %13 None
+OpBranch %14
+%14 = OpLabel
+%15 = OpLoad %int %i
+%26 = OpAccessChain %_ptr_Uniform_int %u_info %int_1
+%27 = OpLoad %int %26
+%29 = OpSLessThan %bool %15 %27
+OpBranchConditional %29 %11 %12
+%11 = OpLabel
+%33 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_IndexBuffer %u_info %int_0
+%34 = OpLoad %_ptr_PhysicalStorageBuffer_IndexBuffer %33
+%35 = OpLoad %int %i
+%37 = OpAccessChain %_ptr_PhysicalStorageBuffer_v3uint %34 %int_0 %35
+%38 = OpLoad %v3uint %37 Aligned 4
+OpStore %readvec %38
+;CHECK-NOT: %38 = OpLoad %v3uint %37 Aligned 4
+;CHECK-NOT: OpStore %readvec %38
+;CHECK: {{%\w+}} = OpConvertPtrToU %ulong %37
+;CHECK: {{%\w+}} = OpLoad %uint %gl_VertexIndex
+;CHECK: {{%\w+}} = OpLoad %uint %gl_InstanceIndex
+;CHECK: {{%\w+}} = OpCompositeConstruct %v4uint %uint_0 {{%\w+}} {{%\w+}} %uint_0
+;CHECK: [[test_result:%\w+]] = OpFunctionCall %bool %)" + kFuncName + R"( %uint_23 %uint_67 {{%\w+}} {{%\w+}} %uint_12
+;CHECK: OpSelectionMerge {{%\w+}} None
+;CHECK: OpBranchConditional [[test_result]] {{%\w+}} {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: {{%\w+}} = OpLoad %v3uint %37 Aligned 4
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: OpBranch {{%\w+}}
+;CHECK: {{%\w+}} = OpLabel
+;CHECK: [[phi_result:%\w+]] = OpPhi %v3uint {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+;CHECK: OpStore %readvec [[phi_result]]
+OpBranch %13
+%13 = OpLabel
+%39 = OpLoad %int %i
+%40 = OpIAdd %int %39 %int_1
+OpStore %i %40
+OpBranch %10
+%12 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
// clang-format on
- SetTargetEnv(SPV_ENV_VULKAN_1_2);
+ SetTargetEnv(SPV_ENV_UNIVERSAL_1_4);
SetAssembleOptions(SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
- SinglePassRunAndMatch<InstBuffAddrCheckPass>(text, true, 7, 23);
+ ValidatorOptions()->scalar_block_layout = true;
+ SinglePassRunAndMatch<InstBuffAddrCheckPass>(text, true, 23);
}
} // namespace
diff --git a/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp b/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
index 7dd10d8fa..24c0bc655 100644
--- a/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/inst_debug_printf_test.cpp
@@ -74,7 +74,7 @@ OpExtension "SPV_KHR_non_semantic_info"
; CHECK: OpExtension "SPV_KHR_storage_buffer_storage_class"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %2 "MainPs" %3 %4
-; CHECK: OpEntryPoint Fragment %2 "MainPs" %3 %4 %gl_FragCoord
+; CHECK: OpEntryPoint Fragment %2 "MainPs" %3 %4
OpExecutionMode %2 OriginUpperLeft
%5 = OpString "Color is %vn"
)";
@@ -87,10 +87,7 @@ OpDecorate %7 DescriptorSet 0
OpDecorate %7 Binding 0
OpDecorate %3 Location 0
OpDecorate %4 Location 0
-; CHECK: OpDecorate %_runtimearr_uint ArrayStride 4
-)" + kOutputDecorations + R"(
-; CHECK: OpDecorate %gl_FragCoord BuiltIn FragCoord
-)";
+)" + kOutputDecorations;
const std::string globals =
R"(%void = OpTypeVoid
@@ -110,14 +107,11 @@ OpDecorate %4 Location 0
%_ptr_Output_v4float = OpTypePointer Output %v4float
%4 = OpVariable %_ptr_Output_v4float Output
; CHECK: %uint = OpTypeInt 32 0
-; CHECK: [[func_type:%\w+]] = OpTypeFunction %void %uint %uint %uint %uint %uint %uint
+; CHECK: [[func_type:%\w+]] = OpTypeFunction %void %uint %uint %uint %uint %uint %uint %uint
; CHECK: %_runtimearr_uint = OpTypeRuntimeArray %uint
)" + kOutputGlobals + R"(
; CHECK: %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
; CHECK: %bool = OpTypeBool
-; CHECK: %_ptr_Input_v4float = OpTypePointer Input %v4float
-; CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
-; CHECK: %v4uint = OpTypeVector %uint 4
)";
// clang-format on
@@ -131,76 +125,64 @@ OpDecorate %4 Location 0
%25 = OpImageSampleImplicitLod %v4float %24 %21
%26 = OpExtInst %void %1 1 %5 %25
; CHECK-NOT: %26 = OpExtInst %void %1 1 %5 %25
-; CHECK: %29 = OpCompositeExtract %float %25 0
-; CHECK: %30 = OpBitcast %uint %29
-; CHECK: %31 = OpCompositeExtract %float %25 1
-; CHECK: %32 = OpBitcast %uint %31
-; CHECK: %33 = OpCompositeExtract %float %25 2
-; CHECK: %34 = OpBitcast %uint %33
-; CHECK: %35 = OpCompositeExtract %float %25 3
-; CHECK: %36 = OpBitcast %uint %35
-; CHECK: %101 = OpFunctionCall %void %inst_printf_stream_write_6 %uint_36 %uint_5 %30 %32 %34 %36
-; CHECK: OpBranch %102
-; CHECK: %102 = OpLabel
+; CHECK: {{%\w+}} = OpCompositeExtract %float %25 0
+; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+; CHECK: {{%\w+}} = OpCompositeExtract %float %25 1
+; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+; CHECK: {{%\w+}} = OpCompositeExtract %float %25 2
+; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+; CHECK: {{%\w+}} = OpCompositeExtract %float %25 3
+; CHECK: {{%\w+}} = OpBitcast %uint {{%\w+}}
+; CHECK: {{%\w+}} = OpFunctionCall %void %inst_printf_stream_write_5 %uint_23 %uint_36 %uint_5 {{%\w+}} {{%\w+}} {{%\w+}} {{%\w+}}
+; CHECK: OpBranch {{%\w+}}
+; CHECK: {{%\w+}} = OpLabel
OpStore %4 %25
OpReturn
OpFunctionEnd
)";
const std::string output_func = R"(
-; CHECK: %inst_printf_stream_write_6 = OpFunction %void None [[func_type]]
-; CHECK: [[param_1:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_2:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_3:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_4:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_5:%\w+]] = OpFunctionParameter %uint
-; CHECK: [[param_6:%\w+]] = OpFunctionParameter %uint
+; CHECK: %inst_printf_stream_write_5 = OpFunction %void None {{%\w+}}
+; CHECK: [[sw_shader_id:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_inst_idx:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_param_1:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_param_2:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_param_3:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_param_4:%\w+]] = OpFunctionParameter %uint
+; CHECK: [[sw_param_5:%\w+]] = OpFunctionParameter %uint
; CHECK: {{%\w+}} = OpLabel
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_1
-; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_12
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_12
-; CHECK: {{%\w+}} = OpArrayLength %uint %inst_printf_output_buffer 2
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_1
+; CHECK: {{%\w+}} = OpAtomicIAdd %uint {{%\w+}} %uint_4 %uint_0 %uint_8
+; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
+; CHECK: {{%\w+}} = OpArrayLength %uint [[output_buffer_var]] 2
; CHECK: {{%\w+}} = OpULessThanEqual %bool {{%\w+}} {{%\w+}}
; CHECK: OpSelectionMerge {{%\w+}} None
; CHECK: OpBranchConditional {{%\w+}} {{%\w+}} {{%\w+}}
; CHECK: {{%\w+}} = OpLabel
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_0
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_12
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} %uint_8
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_1
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_23
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_shader_id]]
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_2
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_1]]
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_inst_idx]]
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_3
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpLoad %v4float %gl_FragCoord
-; CHECK: {{%\w+}} = OpBitcast %v4uint {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 0
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_param_1]]
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_4
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
-; CHECK: {{%\w+}} = OpCompositeExtract %uint {{%\w+}} 1
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_param_2]]
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_5
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} {{%\w+}}
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_param_3]]
+; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_6
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_param_4]]
; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_7
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_2]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_8
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_3]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_9
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_4]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_10
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_5]]
-; CHECK: {{%\w+}} = OpIAdd %uint {{%\w+}} %uint_11
-; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint %inst_printf_output_buffer %uint_2 {{%\w+}}
-; CHECK: OpStore {{%\w+}} [[param_6]]
+; CHECK: {{%\w+}} = OpAccessChain %_ptr_StorageBuffer_uint [[output_buffer_var]] %uint_2 {{%\w+}}
+; CHECK: OpStore {{%\w+}} [[sw_param_5]]
; CHECK: OpBranch {{%\w+}}
; CHECK: {{%\w+}} = OpLabel
; CHECK: OpReturn
diff --git a/third_party/SPIRV-Tools/test/opt/invocation_interlock_placement_test.cpp b/third_party/SPIRV-Tools/test/opt/invocation_interlock_placement_test.cpp
new file mode 100644
index 000000000..2c4ff65eb
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/invocation_interlock_placement_test.cpp
@@ -0,0 +1,613 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "spirv-tools/optimizer.hpp"
+#include "test/opt/pass_fixture.h"
+#include "test/opt/pass_utils.h"
+
+namespace spvtools {
+namespace opt {
+namespace {
+
+using InterlockInvocationPlacementTest = PassTest<::testing::Test>;
+
+TEST_F(InterlockInvocationPlacementTest, CheckUnchangedIfNotFragment) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main"
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+ %2 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(
+ Pass::Status::SuccessWithoutChange,
+ std::get<1>(SinglePassRunAndDisassemble<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false, /* do_validation= */ false)));
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckUnchangedWithoutCapability) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+ %2 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(
+ Pass::Status::SuccessWithoutChange,
+ std::get<1>(SinglePassRunAndDisassemble<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false, /* do_validation= */ false)));
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckSingleBasicBlock) {
+ // We're using OpNoLine as a generic standin for any other instruction, to
+ // test that begin and end aren't moved.
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+; CHECK: OpLabel
+ %2 = OpLabel
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckFunctionCallExtractionBegin) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %foo = OpFunction %void None %1
+; CHECK: OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+ %2 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpReturn
+; CHECK: OpFunctionEnd
+ OpFunctionEnd
+ %main = OpFunction %void None %1
+; CHECK: OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpFunctionCall
+ %4 = OpFunctionCall %void %foo
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckFunctionCallExtractionEnd) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %foo = OpFunction %void None %1
+; CHECK: OpLabel
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ %2 = OpLabel
+ OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+; CHECK: OpFunctionEnd
+ OpFunctionEnd
+ %main = OpFunction %void None %1
+; CHECK: OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpFunctionCall
+ %4 = OpFunctionCall %void %foo
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest,
+ CheckFunctionCallExtractionRepeatedCall) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %foo = OpFunction %void None %1
+; CHECK: OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ %2 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+; CHECK: OpFunctionEnd
+ OpFunctionEnd
+ %main = OpFunction %void None %1
+; CHECK: OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpFunctionCall
+ %4 = OpFunctionCall %void %foo
+; CHECK-NEXT: OpFunctionCall
+ %5 = OpFunctionCall %void %foo
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest,
+ CheckFunctionCallExtractionNestedCall) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %foo = OpFunction %void None %1
+; CHECK: OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ %2 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+; CHECK: OpFunctionEnd
+ OpFunctionEnd
+ %bar = OpFunction %void None %1
+; CHECK: OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ %3 = OpLabel
+ %4 = OpFunctionCall %void %foo
+ OpReturn
+; CHECK: OpFunctionEnd
+ OpFunctionEnd
+ %main = OpFunction %void None %1
+; CHECK: OpLabel
+ %5 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpFunctionCall
+ %6 = OpFunctionCall %void %bar
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckLoopExtraction) {
+ // Tests that any begin or end instructions in a loop are moved outside of the
+ // loop.
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+ %2 = OpLabel
+; CHECK: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpBranch %3
+
+ %3 = OpLabel
+ OpLoopMerge %3 %4 None
+; CHECK: OpBranchConditional
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpBranchConditional %true %4 %5
+
+ %4 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK: OpBranch
+ OpBranch %3
+
+; CHECK-NEXT: OpLabel
+ %5 = OpLabel
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckAddBeginToElse) {
+ // Test that if there is a begin in a single branch of a conditional, begin
+ // will be added to the other branch.
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+ %2 = OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+ OpSelectionMerge %5 None
+; CHECK: OpBranchConditional
+ OpBranchConditional %true %3 %4
+
+; CHECK-NEXT: OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpBranch
+ OpBranch %5
+
+ %4 = OpLabel
+; CHECK: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpBranch
+ OpBranch %5
+
+; CHECK-NEXT: OpLabel
+ %5 = OpLabel
+ OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckAddEndToElse) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+ %2 = OpLabel
+; CHECK: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpSelectionMerge %5 None
+; CHECK: OpBranchConditional
+ OpBranchConditional %true %3 %4
+
+; CHECK-NEXT: OpLabel
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpBranch
+ OpBranch %5
+
+ %4 = OpLabel
+; CHECK: OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpBranch
+ OpBranch %5
+
+; CHECK-NEXT: OpLabel
+ %5 = OpLabel
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckSplitIfWithoutElseBegin) {
+ // Test that if there is a begin in the then branch of a conditional, and no
+ // else branch, an else branch with a begin will created.
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+ %2 = OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+ OpSelectionMerge %5 None
+; CHECK: OpBranchConditional
+ OpBranchConditional %true %3 %5
+
+; CHECK-NEXT: OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpBranch
+
+; CHECK-NEXT: OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpBranch %5
+
+; CHECK: OpLabel
+ %5 = OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckSplitIfWithoutElseEnd) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+ %2 = OpLabel
+
+; CHECK: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpSelectionMerge [[merge:%\d+]]
+ OpSelectionMerge %5 None
+; CHECK-NEXT: OpBranchConditional %true [[then:%\d+]] [[else:%\d+]]
+ OpBranchConditional %true %3 %5
+
+; CHECK-NEXT: [[else]] = OpLabel
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpBranch [[merge]]
+
+; CHECK-NEXT: [[then]] = OpLabel
+ %3 = OpLabel
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpBranch [[merge]]
+ OpBranch %5
+
+; CHECK-NEXT: [[merge]] = OpLabel
+ %5 = OpLabel
+; CHECK-NEXT: OpReturn
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(InterlockInvocationPlacementTest, CheckSplitSwitch) {
+ // Test that if there is a begin or end in a single branch of a switch, begin
+ // or end will be added to all the other branches.
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ OpName %main "main"
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+ %1 = OpTypeFunction %void
+ %main = OpFunction %void None %1
+
+; CHECK: OpLabel
+ %2 = OpLabel
+; CHECK-NEXT: OpSelectionMerge [[merge:%\d+]]
+ OpSelectionMerge %8 None
+; CHECK-NEXT: OpSwitch %uint_1 [[default:%\d+]] 0 [[case_0:%\d+]] 1 [[case_1:%\d+]] 2 [[case_2:%\d+]]
+ OpSwitch %uint_1 %8 0 %4 1 %5 2 %8
+
+; CHECK-NEXT: [[case_2]] = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpBranch [[merge]]
+
+; CHECK-NEXT: [[default]] = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpBranch [[merge]]
+
+; CHECK-NEXT: [[case_0]] = OpLabel
+ %4 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpBranch [[merge]]
+ OpBranch %8
+
+; CHECK-NEXT: [[case_1]] = OpLabel
+ %5 = OpLabel
+; CHECK-NEXT: OpBeginInvocationInterlockEXT
+; CHECK-NOT: OpEndInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpNoLine
+ OpNoLine
+; CHECK-NEXT: OpBranch [[merge]]
+ OpBranch %8
+
+; CHECK-NEXT: [[merge]] = OpLabel
+ %8 = OpLabel
+; CHECK-NOT: OpBeginInvocationInterlockEXT
+ OpBeginInvocationInterlockEXT
+; CHECK-NEXT: OpEndInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result = SinglePassRunAndMatch<InvocationInterlockPlacementPass>(
+ kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+} // namespace
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp b/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
index 1acbefe7e..621fe8cf0 100644
--- a/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/ir_context_test.cpp
@@ -1173,6 +1173,254 @@ TEST_P(TargetEnvCompareTest, Case) {
}
}
+TEST_F(IRContextTest, ReturnsTrueWhenExtensionIsRemoved) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 1);
+
+ EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock));
+
+ EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 0);
+}
+
+TEST_F(IRContextTest, ReturnsFalseWhenExtensionIsNotRemoved) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_device_group"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 1);
+
+ EXPECT_FALSE(ctx->RemoveExtension(kSPV_KHR_shader_clock));
+
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 1);
+}
+
+TEST_F(IRContextTest, RemovesExtensionIfLast) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_device_group"
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 2);
+
+ EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock));
+
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 1);
+}
+
+TEST_F(IRContextTest, RemovesExtensionIfFirst) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_shader_clock"
+ OpExtension "SPV_KHR_device_group"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 2);
+
+ EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock));
+
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_device_group));
+ EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 1);
+}
+
+TEST_F(IRContextTest, RemovesMultipleExtensions) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_shader_clock"
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 2);
+
+ EXPECT_TRUE(ctx->RemoveExtension(kSPV_KHR_shader_clock));
+
+ EXPECT_FALSE(ctx->get_feature_mgr()->HasExtension(kSPV_KHR_shader_clock));
+ EXPECT_EQ(std::distance(ctx->module()->extension_begin(),
+ ctx->module()->extension_end()),
+ 0);
+}
+
+TEST_F(IRContextTest, ReturnsTrueWhenCapabilityIsRemoved) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability ShaderClockKHR
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::ShaderClockKHR));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 2);
+
+ EXPECT_TRUE(ctx->RemoveCapability(spv::Capability::ShaderClockKHR));
+
+ EXPECT_FALSE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::ShaderClockKHR));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 1);
+}
+
+TEST_F(IRContextTest, ReturnsFalseWhenCapabilityIsNotRemoved) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability DeviceGroup
+ OpExtension "SPV_KHR_device_group"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 2);
+
+ EXPECT_FALSE(ctx->RemoveCapability(spv::Capability::ShaderClockKHR));
+
+ EXPECT_TRUE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 2);
+}
+
+TEST_F(IRContextTest, RemovesMultipleCapabilities) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability DeviceGroup
+ OpCapability DeviceGroup
+ OpExtension "SPV_KHR_device_group"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %6 = OpTypeFunction %void
+ %1 = OpFunction %void None %6
+ %9 = OpLabel
+ OpReturn
+ OpFunctionEnd)";
+
+ std::unique_ptr<IRContext> ctx =
+ BuildModule(SPV_ENV_UNIVERSAL_1_6, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ EXPECT_TRUE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 3);
+
+ EXPECT_TRUE(ctx->RemoveCapability(spv::Capability::DeviceGroup));
+
+ EXPECT_FALSE(
+ ctx->get_feature_mgr()->HasCapability(spv::Capability::DeviceGroup));
+ EXPECT_EQ(std::distance(ctx->module()->capability_begin(),
+ ctx->module()->capability_end()),
+ 1);
+}
+
INSTANTIATE_TEST_SUITE_P(
TestCase, TargetEnvCompareTest,
::testing::Values(
diff --git a/third_party/SPIRV-Tools/test/opt/modify_maximal_reconvergence_test.cpp b/third_party/SPIRV-Tools/test/opt/modify_maximal_reconvergence_test.cpp
new file mode 100644
index 000000000..bef9237cf
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/modify_maximal_reconvergence_test.cpp
@@ -0,0 +1,312 @@
+// Copyright (c) 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "assembly_builder.h"
+#include "pass_fixture.h"
+#include "pass_utils.h"
+
+namespace {
+
+using namespace spvtools;
+
+using ModifyMaximalReconvergenceTest = opt::PassTest<::testing::Test>;
+
+TEST_F(ModifyMaximalReconvergenceTest, AddNoEntryPoint) {
+ const std::string text = R"(
+; CHECK-NOT: OpExtension
+OpCapability Kernel
+OpCapability Linkage
+OpMemoryModel Logical OpenCL
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddSingleEntryPoint) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %main MaximallyReconvergesKHR
+
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpName %main "main"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddExtensionExists) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %main MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpName %main "main"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddExecutionModeExists) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %main LocalSize 1 1 1
+; CHECK-NEXT: OpExecutionMode %main MaximallyReconvergesKHR
+; CHECK-NOT: OpExecutionMode %main MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+OpName %main "main"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPoints) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
+; CHECK: OpExecutionMode %frag MaximallyReconvergesKHR
+
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %comp "main"
+OpEntryPoint Fragment %frag "main"
+OpExecutionMode %comp LocalSize 1 1 1
+OpExecutionMode %frag OriginUpperLeft
+OpName %comp "comp"
+OpName %frag "frag"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%comp = OpFunction %void None %void_fn
+%entry1 = OpLabel
+OpReturn
+OpFunctionEnd
+%frag = OpFunction %void None %void_fn
+%entry2 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPointsOneFunc) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
+; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
+
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %comp "main1"
+OpEntryPoint GLCompute %comp "main2"
+OpExecutionMode %comp LocalSize 1 1 1
+OpName %comp "comp"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%comp = OpFunction %void None %void_fn
+%entry1 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, AddTwoEntryPointsOneExecutionMode) {
+ const std::string text = R"(
+; CHECK: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %comp MaximallyReconvergesKHR
+; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
+; CHECK: OpExecutionMode %frag MaximallyReconvergesKHR
+; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %comp "main"
+OpEntryPoint Fragment %frag "main"
+OpExecutionMode %comp LocalSize 1 1 1
+OpExecutionMode %frag OriginUpperLeft
+OpExecutionMode %comp MaximallyReconvergesKHR
+OpName %comp "comp"
+OpName %frag "frag"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%comp = OpFunction %void None %void_fn
+%entry1 = OpLabel
+OpReturn
+OpFunctionEnd
+%frag = OpFunction %void None %void_fn
+%entry2 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, true);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, RemoveNoEntryPoint) {
+ const std::string text = R"(OpCapability Kernel
+OpCapability Linkage
+OpMemoryModel Logical OpenCL
+)";
+
+ SinglePassRunAndCheck<opt::ModifyMaximalReconvergence>(text, text, false,
+ true, false);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, RemoveOnlyExtension) {
+ const std::string text = R"(
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %main LocalSize 1 1 1
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpName %main "main"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, RemoveSingleEntryPoint) {
+ const std::string text = R"(
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %main LocalSize 1 1 1
+; CHECK-NOT: OpExecutionMode %main MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+OpName %main "main"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, RemoveTwoEntryPointsOneExecutionMode) {
+ const std::string text = R"(
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %comp LocalSize 1 1 1
+; CHECK-NEXT: OpExecutionMode %frag OriginUpperLeft
+; CHECK-NOT: OpExecutionMode %comp MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %comp "main"
+OpEntryPoint Fragment %frag "main"
+OpExecutionMode %comp LocalSize 1 1 1
+OpExecutionMode %comp MaximallyReconvergesKHR
+OpExecutionMode %frag OriginUpperLeft
+OpName %comp "comp"
+OpName %frag "frag"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%comp = OpFunction %void None %void_fn
+%entry1 = OpLabel
+OpReturn
+OpFunctionEnd
+%frag = OpFunction %void None %void_fn
+%entry2 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
+}
+
+TEST_F(ModifyMaximalReconvergenceTest, RemoveTwoEntryPoints) {
+ const std::string text = R"(
+; CHECK-NOT: OpExtension "SPV_KHR_maximal_reconvergence"
+; CHECK: OpExecutionMode %comp LocalSize 1 1 1
+; CHECK-NEXT: OpExecutionMode %frag OriginUpperLeft
+; CHECK-NOT: OpExecutionMode {{%\w}} MaximallyReconvergesKHR
+
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %comp "main"
+OpEntryPoint Fragment %frag "main"
+OpExecutionMode %comp LocalSize 1 1 1
+OpExecutionMode %comp MaximallyReconvergesKHR
+OpExecutionMode %frag OriginUpperLeft
+OpExecutionMode %frag MaximallyReconvergesKHR
+OpName %comp "comp"
+OpName %frag "frag"
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%comp = OpFunction %void None %void_fn
+%entry1 = OpLabel
+OpReturn
+OpFunctionEnd
+%frag = OpFunction %void None %void_fn
+%entry2 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ SinglePassRunAndMatch<opt::ModifyMaximalReconvergence>(text, true, false);
+}
+
+} // namespace
diff --git a/third_party/SPIRV-Tools/test/opt/switch_descriptorset_test.cpp b/third_party/SPIRV-Tools/test/opt/switch_descriptorset_test.cpp
new file mode 100644
index 000000000..f26178f82
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/switch_descriptorset_test.cpp
@@ -0,0 +1,193 @@
+// Copyright (c) 2023 LunarG Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Bindless Check Instrumentation Tests.
+// Tests ending with V2 use version 2 record format.
+
+#include <string>
+#include <vector>
+
+#include "test/opt/pass_fixture.h"
+#include "test/opt/pass_utils.h"
+
+namespace spvtools {
+namespace opt {
+namespace {
+
+using SwitchDescriptorSetTest = PassTest<::testing::Test>;
+
+TEST_F(SwitchDescriptorSetTest, Basic) {
+ // #version 450
+ // #extension GL_EXT_buffer_reference : enable
+ //
+ // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct;
+ //
+ // layout(set = 7, binding = 7) uniform ufoo {
+ // bufStruct data;
+ // uint offset;
+ // } u_info;
+ //
+ // layout(buffer_reference, std140) buffer bufStruct {
+ // layout(offset = 0) int a[2];
+ // layout(offset = 32) int b;
+ // };
+ //
+ // void main() {
+ // u_info.data.b = 0xca7;
+ // }
+
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability PhysicalStorageBufferAddresses
+OpExtension "SPV_EXT_physical_storage_buffer"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_buffer_reference"
+OpName %main "main"
+OpName %ufoo "ufoo"
+OpMemberName %ufoo 0 "data"
+OpMemberName %ufoo 1 "offset"
+OpName %bufStruct "bufStruct"
+OpMemberName %bufStruct 0 "a"
+OpMemberName %bufStruct 1 "b"
+OpName %u_info "u_info"
+OpMemberDecorate %ufoo 0 Offset 0
+OpMemberDecorate %ufoo 1 Offset 8
+OpDecorate %ufoo Block
+OpDecorate %_arr_int_uint_2 ArrayStride 16
+OpMemberDecorate %bufStruct 0 Offset 0
+OpMemberDecorate %bufStruct 1 Offset 32
+OpDecorate %bufStruct Block
+OpDecorate %u_info DescriptorSet 7
+;CHECK: OpDecorate %u_info DescriptorSet 31
+OpDecorate %u_info Binding 7
+;CHECK: OpDecorate %u_info Binding 7
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
+%uint = OpTypeInt 32 0
+%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
+%int = OpTypeInt 32 1
+%uint_2 = OpConstant %uint 2
+%_arr_int_uint_2 = OpTypeArray %int %uint_2
+%bufStruct = OpTypeStruct %_arr_int_uint_2 %int
+%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
+%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
+%u_info = OpVariable %_ptr_Uniform_ufoo Uniform
+%int_0 = OpConstant %int 0
+%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
+%int_1 = OpConstant %int 1
+%int_3239 = OpConstant %int 3239
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+%main = OpFunction %void None %3
+%5 = OpLabel
+%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
+%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
+%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
+OpReturn
+OpFunctionEnd
+)";
+ // clang-format off
+
+ SinglePassRunAndMatch<SwitchDescriptorSetPass>(spirv, true, 7, 31);
+}
+
+
+// Make sure DescriptorSet decorations that don't match the requested number
+// are left unchanged.
+TEST_F(SwitchDescriptorSetTest, Unchanged) {
+ // #version 450
+ // #extension GL_EXT_buffer_reference : enable
+ //
+ // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct;
+ //
+ // layout(set = 11, binding = 7) uniform ufoo {
+ // bufStruct data;
+ // uint offset;
+ // } u_info;
+ //
+ // layout(buffer_reference, std140) buffer bufStruct {
+ // layout(offset = 0) int a[2];
+ // layout(offset = 32) int b;
+ // };
+ //
+ // void main() {
+ // u_info.data.b = 0xca7;
+ // }
+
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability PhysicalStorageBufferAddresses
+OpExtension "SPV_EXT_physical_storage_buffer"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpSource GLSL 450
+OpSourceExtension "GL_EXT_buffer_reference"
+OpName %main "main"
+OpName %ufoo "ufoo"
+OpMemberName %ufoo 0 "data"
+OpMemberName %ufoo 1 "offset"
+OpName %bufStruct "bufStruct"
+OpMemberName %bufStruct 0 "a"
+OpMemberName %bufStruct 1 "b"
+OpName %u_info "u_info"
+OpMemberDecorate %ufoo 0 Offset 0
+OpMemberDecorate %ufoo 1 Offset 8
+OpDecorate %ufoo Block
+OpDecorate %_arr_int_uint_2 ArrayStride 16
+OpMemberDecorate %bufStruct 0 Offset 0
+OpMemberDecorate %bufStruct 1 Offset 32
+OpDecorate %bufStruct Block
+OpDecorate %u_info DescriptorSet 11
+;CHECK: OpDecorate %u_info DescriptorSet 11
+OpDecorate %u_info Binding 7
+;CHECK: OpDecorate %u_info Binding 7
+%void = OpTypeVoid
+%3 = OpTypeFunction %void
+OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
+%uint = OpTypeInt 32 0
+%ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
+%int = OpTypeInt 32 1
+%uint_2 = OpConstant %uint 2
+%_arr_int_uint_2 = OpTypeArray %int %uint_2
+%bufStruct = OpTypeStruct %_arr_int_uint_2 %int
+%_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
+%_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
+%u_info = OpVariable %_ptr_Uniform_ufoo Uniform
+%int_0 = OpConstant %int 0
+%_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
+%int_1 = OpConstant %int 1
+%int_3239 = OpConstant %int 3239
+%_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
+%main = OpFunction %void None %3
+%5 = OpLabel
+%17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
+%18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
+%22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
+OpReturn
+OpFunctionEnd
+)";
+ // clang-format off
+
+ SinglePassRunAndMatch<SwitchDescriptorSetPass>(spirv, true, 7, 31);
+}
+
+} // namespace
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/trim_capabilities_pass_test.cpp b/third_party/SPIRV-Tools/test/opt/trim_capabilities_pass_test.cpp
new file mode 100644
index 000000000..d74ccdf2f
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/opt/trim_capabilities_pass_test.cpp
@@ -0,0 +1,2665 @@
+// Copyright (c) 2023 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "spirv-tools/optimizer.hpp"
+#include "test/opt/pass_fixture.h"
+#include "test/opt/pass_utils.h"
+
+namespace spvtools {
+namespace opt {
+namespace {
+
+using TrimCapabilitiesPassTest = PassTest<::testing::Test>;
+
+TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) {
+ // Those are expected changes caused by the test process:
+ // - SPV is assembled. -> capability goes from text to number.
+ // - SPV is optimized.
+ // - SPV is disassembled -> capability goes from number to text.
+ // - CHECK rule compares both text versions.
+ // Because some capabilities share the same number (aliases), the text
+ // compared with the CHECK rules depends on which alias is the first on the
+ // SPIRV-Headers enum. This could change, and we want to easily distinguish
+ // real failure from alias order change. This test is only here to list known
+ // alias transformations. If this test breaks, it's not a bug in the
+ // optimization pass, but just the SPIRV-Headers enum order that has changed.
+ // If that happens, tests needs to be updated to the correct alias is used in
+ // the CHECK rule.
+ const std::string kTest = R"(
+ OpCapability Linkage
+ OpCapability StorageUniform16
+ OpCapability StorageUniformBufferBlock16
+ OpCapability ShaderViewportIndexLayerNV
+ OpCapability FragmentBarycentricNV
+ OpCapability ShadingRateNV
+ OpCapability ShaderNonUniformEXT
+ OpCapability RuntimeDescriptorArrayEXT
+ OpCapability InputAttachmentArrayDynamicIndexingEXT
+ OpCapability UniformTexelBufferArrayDynamicIndexingEXT
+ OpCapability StorageTexelBufferArrayDynamicIndexingEXT
+ OpCapability UniformBufferArrayNonUniformIndexingEXT
+ OpCapability SampledImageArrayNonUniformIndexingEXT
+ OpCapability StorageBufferArrayNonUniformIndexingEXT
+ OpCapability StorageImageArrayNonUniformIndexingEXT
+ OpCapability InputAttachmentArrayNonUniformIndexingEXT
+ OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
+ OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
+ OpCapability VulkanMemoryModelKHR
+ OpCapability VulkanMemoryModelDeviceScopeKHR
+ OpCapability PhysicalStorageBufferAddressesEXT
+ OpCapability DemoteToHelperInvocationEXT
+ OpCapability DotProductInputAllKHR
+ OpCapability DotProductInput4x8BitKHR
+ OpCapability DotProductInput4x8BitPackedKHR
+ OpCapability DotProductKHR
+ OpCapability ComputeDerivativeGroupQuadsNV
+ OpCapability ComputeDerivativeGroupLinearNV
+; CHECK: OpCapability Linkage
+; CHECK-NOT: OpCapability StorageUniform16
+; CHECK-NOT: OpCapability StorageUniformBufferBlock16
+; CHECK-NOT: OpCapability ShaderViewportIndexLayerNV
+; CHECK-NOT: OpCapability FragmentBarycentricNV
+; CHECK-NOT: OpCapability ShadingRateNV
+; CHECK-NOT: OpCapability ShaderNonUniformEXT
+; CHECK-NOT: OpCapability RuntimeDescriptorArrayEXT
+; CHECK-NOT: OpCapability InputAttachmentArrayDynamicIndexingEXT
+; CHECK-NOT: OpCapability UniformTexelBufferArrayDynamicIndexingEXT
+; CHECK-NOT: OpCapability StorageTexelBufferArrayDynamicIndexingEXT
+; CHECK-NOT: OpCapability UniformBufferArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability SampledImageArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability StorageBufferArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability StorageImageArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability InputAttachmentArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
+; CHECK-NOT: OpCapability VulkanMemoryModelKHR
+; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScopeKHR
+; CHECK-NOT: OpCapability PhysicalStorageBufferAddressesEXT
+; CHECK-NOT: OpCapability DemoteToHelperInvocationEXT
+; CHECK-NOT: OpCapability DotProductInputAllKHR
+; CHECK-NOT: OpCapability DotProductInput4x8BitKHR
+; CHECK-NOT: OpCapability DotProductInput4x8BitPackedKHR
+; CHECK-NOT: OpCapability DotProductKHR
+; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV
+; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV
+; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
+; CHECK: OpCapability StorageBuffer16BitAccess
+; CHECK: OpCapability ShaderViewportIndexLayerEXT
+; CHECK: OpCapability FragmentBarycentricKHR
+; CHECK: OpCapability FragmentDensityEXT
+; CHECK: OpCapability ShaderNonUniform
+; CHECK: OpCapability RuntimeDescriptorArray
+; CHECK: OpCapability InputAttachmentArrayDynamicIndexing
+; CHECK: OpCapability UniformTexelBufferArrayDynamicIndexing
+; CHECK: OpCapability StorageTexelBufferArrayDynamicIndexing
+; CHECK: OpCapability UniformBufferArrayNonUniformIndexing
+; CHECK: OpCapability SampledImageArrayNonUniformIndexing
+; CHECK: OpCapability StorageBufferArrayNonUniformIndexing
+; CHECK: OpCapability StorageImageArrayNonUniformIndexing
+; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
+; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndexing
+; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
+; CHECK: OpCapability VulkanMemoryModel
+; CHECK: OpCapability VulkanMemoryModelDeviceScope
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability DemoteToHelperInvocation
+; CHECK: OpCapability DotProductInputAll
+; CHECK: OpCapability DotProductInput4x8Bit
+; CHECK: OpCapability DotProductInput4x8BitPacked
+; CHECK: OpCapability DotProduct
+ OpMemoryModel Logical Vulkan
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result =
+ SinglePassRunAndMatch<EmptyPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, LinkagePreventsChanges) {
+ const std::string kTest = R"(
+ OpCapability Linkage
+ OpCapability ClipDistance
+ OpCapability CullDistance
+ OpCapability DemoteToHelperInvocation
+ OpCapability DeviceGroup
+ OpCapability DrawParameters
+ OpCapability Float16
+ OpCapability Float64
+ OpCapability FragmentBarycentricKHR
+ OpCapability FragmentFullyCoveredEXT
+ OpCapability FragmentShadingRateKHR
+ OpCapability GroupNonUniform
+ OpCapability GroupNonUniformArithmetic
+ OpCapability GroupNonUniformBallot
+ OpCapability GroupNonUniformQuad
+ OpCapability GroupNonUniformShuffle
+ OpCapability Image1D
+ OpCapability ImageBuffer
+ OpCapability ImageGatherExtended
+ OpCapability ImageMSArray
+ OpCapability ImageQuery
+ OpCapability InputAttachment
+ OpCapability InputAttachmentArrayNonUniformIndexing
+ OpCapability Int16
+ OpCapability Int64
+ OpCapability Int64Atomics
+ OpCapability Int64ImageEXT
+ OpCapability MeshShadingNV
+ OpCapability MinLod
+ OpCapability MultiView
+ OpCapability MultiViewport
+ OpCapability PhysicalStorageBufferAddresses
+ OpCapability RayQueryKHR
+ OpCapability RayTracingKHR
+ OpCapability RayTracingNV
+ OpCapability RayTraversalPrimitiveCullingKHR
+ OpCapability RuntimeDescriptorArray
+ OpCapability SampleMaskPostDepthCoverage
+ OpCapability SampleRateShading
+ OpCapability Sampled1D
+ OpCapability SampledBuffer
+ OpCapability SampledImageArrayNonUniformIndexing
+ OpCapability Shader
+ OpCapability ShaderClockKHR
+ OpCapability ShaderLayer
+ OpCapability ShaderNonUniform
+ OpCapability ShaderViewportIndex
+ OpCapability ShaderViewportIndexLayerEXT
+ OpCapability SparseResidency
+ OpCapability StencilExportEXT
+ OpCapability StorageImageArrayNonUniformIndexingEXT
+ OpCapability StorageImageExtendedFormats
+ OpCapability StorageImageReadWithoutFormat
+ OpCapability StorageImageWriteWithoutFormat
+ OpCapability StorageInputOutput16
+ OpCapability StoragePushConstant16
+ OpCapability StorageTexelBufferArrayNonUniformIndexing
+ OpCapability StorageUniform16
+ OpCapability StorageUniformBufferBlock16
+ OpCapability Tessellation
+ OpCapability UniformTexelBufferArrayNonUniformIndexing
+ OpCapability VulkanMemoryModel
+ OpExtension "SPV_EXT_fragment_fully_covered"
+ OpExtension "SPV_EXT_shader_image_int64"
+ OpExtension "SPV_EXT_shader_stencil_export"
+ OpExtension "SPV_EXT_shader_viewport_index_layer"
+ OpExtension "SPV_KHR_fragment_shader_barycentric"
+ OpExtension "SPV_KHR_fragment_shading_rate"
+ OpExtension "SPV_KHR_post_depth_coverage"
+ OpExtension "SPV_KHR_ray_query"
+ OpExtension "SPV_KHR_ray_tracing"
+ OpExtension "SPV_KHR_shader_clock"
+ OpExtension "SPV_NV_mesh_shader"
+ OpExtension "SPV_NV_ray_tracing"
+ OpExtension "SPV_NV_viewport_array2"
+; CHECK: OpCapability Linkage
+; CHECK: OpCapability ClipDistance
+; CHECK: OpCapability CullDistance
+; CHECK: OpCapability DemoteToHelperInvocation
+; CHECK: OpCapability DeviceGroup
+; CHECK: OpCapability DrawParameters
+; CHECK: OpCapability Float16
+; CHECK: OpCapability Float64
+; CHECK: OpCapability FragmentBarycentricKHR
+; CHECK: OpCapability FragmentFullyCoveredEXT
+; CHECK: OpCapability FragmentShadingRateKHR
+; CHECK: OpCapability GroupNonUniform
+; CHECK: OpCapability GroupNonUniformArithmetic
+; CHECK: OpCapability GroupNonUniformBallot
+; CHECK: OpCapability GroupNonUniformQuad
+; CHECK: OpCapability GroupNonUniformShuffle
+; CHECK: OpCapability Image1D
+; CHECK: OpCapability ImageBuffer
+; CHECK: OpCapability ImageGatherExtended
+; CHECK: OpCapability ImageMSArray
+; CHECK: OpCapability ImageQuery
+; CHECK: OpCapability InputAttachment
+; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
+; CHECK: OpCapability Int16
+; CHECK: OpCapability Int64
+; CHECK: OpCapability Int64Atomics
+; CHECK: OpCapability Int64ImageEXT
+; CHECK: OpCapability MeshShadingNV
+; CHECK: OpCapability MinLod
+; CHECK: OpCapability MultiView
+; CHECK: OpCapability MultiViewport
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability RayQueryKHR
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpCapability RayTracingNV
+; CHECK: OpCapability RayTraversalPrimitiveCullingKHR
+; CHECK: OpCapability RuntimeDescriptorArray
+; CHECK: OpCapability SampleMaskPostDepthCoverage
+; CHECK: OpCapability SampleRateShading
+; CHECK: OpCapability Sampled1D
+; CHECK: OpCapability SampledBuffer
+; CHECK: OpCapability SampledImageArrayNonUniformIndexing
+; CHECK: OpCapability Shader
+; CHECK: OpCapability ShaderClockKHR
+; CHECK: OpCapability ShaderLayer
+; CHECK: OpCapability ShaderNonUniform
+; CHECK: OpCapability ShaderViewportIndex
+; CHECK: OpCapability ShaderViewportIndexLayerEXT
+; CHECK: OpCapability SparseResidency
+; CHECK: OpCapability StencilExportEXT
+; CHECK: OpCapability StorageImageArrayNonUniformIndexing
+; CHECK: OpCapability StorageImageExtendedFormats
+; CHECK: OpCapability StorageImageReadWithoutFormat
+; CHECK: OpCapability StorageImageWriteWithoutFormat
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpCapability StoragePushConstant16
+; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
+; CHECK: OpCapability Tessellation
+; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndex
+; CHECK: OpCapability VulkanMemoryModel
+; CHECK: OpExtension "SPV_EXT_fragment_fully_covered"
+; CHECK: OpExtension "SPV_EXT_shader_image_int64"
+; CHECK: OpExtension "SPV_EXT_shader_stencil_export"
+; CHECK: OpExtension "SPV_EXT_shader_viewport_index_layer"
+; CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric"
+; CHECK: OpExtension "SPV_KHR_fragment_shading_rate"
+; CHECK: OpExtension "SPV_KHR_post_depth_coverage"
+; CHECK: OpExtension "SPV_KHR_ray_query"
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpExtension "SPV_KHR_shader_clock"
+; CHECK: OpExtension "SPV_NV_mesh_shader"
+; CHECK: OpExtension "SPV_NV_ray_tracing"
+; CHECK: OpExtension "SPV_NV_viewport_array2"
+ OpMemoryModel Logical Vulkan
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_3);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, KeepShader) {
+ const std::string kTest = R"(
+ OpCapability Shader
+; CHECK: OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, KeepShaderClockWhenInUse) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Int64
+ OpCapability ShaderClockKHR
+ OpExtension "SPV_KHR_shader_clock"
+; CHECK: OpCapability ShaderClockKHR
+; CHECK: OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %ulong = OpTypeInt 64 0
+ %scope = OpConstant %uint 1
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ %7 = OpReadClockKHR %ulong %scope
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, TrimShaderClockWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Int64
+ OpCapability ShaderClockKHR
+ OpExtension "SPV_KHR_shader_clock"
+; CHECK-NOT: OpCapability ShaderClockKHR
+; CHECK-NOT: OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemains) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Groups
+ OpExtension "SPV_AMD_shader_ballot"
+; CHECK: OpCapability Groups
+; CHECK: OpExtension "SPV_AMD_shader_ballot"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %1 = OpTypeFunction %void
+ %uint_0 = OpConstant %uint 0
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ %4 = OpGroupIAddNonUniformAMD %uint %uint_0 ExclusiveScan %uint_0
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemoved) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Groups
+ OpExtension "SPV_AMD_shader_ballot"
+; CHECK-NOT: OpCapability Groups
+; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, MinLod_RemovedIfNotUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Sampled1D
+ OpCapability MinLod
+; CHECK-NOT: OpCapability MinLod
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
+ %ptr_type_image = OpTypePointer UniformConstant %type_image
+ %type_sampler = OpTypeSampler
+ %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
+ %float_0 = OpConstant %float 0
+ %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+ %image = OpVariable %ptr_type_image UniformConstant
+ %sampler = OpVariable %ptr_type_sampler UniformConstant
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ %21 = OpLoad %type_image %image
+ %22 = OpLoad %type_sampler %sampler
+ %24 = OpSampledImage %type_sampled_image %21 %22
+ %25 = OpImageSampleImplicitLod %v4float %24 %float_000
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, MinLod_RemainsWithOpImageSampleImplicitLod) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Sampled1D
+ OpCapability MinLod
+; CHECK: OpCapability MinLod
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %float = OpTypeFloat 32
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
+ %ptr_type_image = OpTypePointer UniformConstant %type_image
+ %type_sampler = OpTypeSampler
+ %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
+ %float_0 = OpConstant %float 0
+ %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+ %image = OpVariable %ptr_type_image UniformConstant
+ %sampler = OpVariable %ptr_type_sampler UniformConstant
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ %21 = OpLoad %type_image %image
+ %22 = OpLoad %type_sampler %sampler
+ %24 = OpSampledImage %type_sampled_image %21 %22
+ %25 = OpImageSampleImplicitLod %v4float %24 %float_000 MinLod %float_0
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ MinLod_RemainsWithOpImageSparseSampleImplicitLod) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability SparseResidency
+ OpCapability ImageGatherExtended
+ OpCapability MinLod
+; CHECK: OpCapability MinLod
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main"
+ OpExecutionMode %2 OriginUpperLeft
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %float = OpTypeFloat 32
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
+ %ptr_type_image = OpTypePointer UniformConstant %type_image
+ %type_sampler = OpTypeSampler
+ %ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
+%type_sampled_image = OpTypeSampledImage %type_image
+ %sparse_struct = OpTypeStruct %uint %v4float
+ %float_0 = OpConstant %float 0
+ %float_00 = OpConstantComposite %v2float %float_0 %float_0
+ %float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+ %image = OpVariable %ptr_type_image UniformConstant
+ %sampler = OpVariable %ptr_type_sampler UniformConstant
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ %21 = OpLoad %type_image %image
+ %22 = OpLoad %type_sampler %sampler
+ %24 = OpSampledImage %type_sampled_image %21 %22
+ %25 = OpImageSparseSampleImplicitLod %sparse_struct %24 %float_00 MinLod %float_0
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, MinLod_DetectsMinLodWithBitmaskImageOperand) {
+ const std::string kTest = R"(
+ OpCapability MinLod
+; CHECK: OpCapability MinLod
+ OpCapability Shader
+ OpCapability SparseResidency
+ OpCapability ImageGatherExtended
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %1 "main"
+ OpExecutionMode %1 OriginUpperLeft
+ %type_sampler = OpTypeSampler
+ %int = OpTypeInt 32 1
+ %float = OpTypeFloat 32
+ %v2int = OpTypeVector %int 2
+ %v2float = OpTypeVector %float 2
+ %v4float = OpTypeVector %float 4
+ %ptr_sampler = OpTypePointer UniformConstant %type_sampler
+ %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
+ %ptr_image = OpTypePointer UniformConstant %type_image
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %type_sampled_image = OpTypeSampledImage %type_image
+ %type_struct = OpTypeStruct %uint %v4float
+
+ %int_1 = OpConstant %int 1
+ %float_0 = OpConstant %float 0
+ %float_1 = OpConstant %float 1
+ %8 = OpConstantComposite %v2float %float_0 %float_0
+ %12 = OpConstantComposite %v2int %int_1 %int_1
+
+ %2 = OpVariable %ptr_sampler UniformConstant
+ %3 = OpVariable %ptr_image UniformConstant
+ %27 = OpTypeFunction %void
+ %1 = OpFunction %void None %27
+ %28 = OpLabel
+ %29 = OpLoad %type_image %3
+ %30 = OpLoad %type_sampler %2
+ %31 = OpSampledImage %type_sampled_image %29 %30
+ %32 = OpImageSparseSampleImplicitLod %type_struct %31 %8 ConstOffset|MinLod %12 %float_0
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointer_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer Input %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointer_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer Input %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+ %array = OpTypeArray %half %uint_1
+ %ptr = OpTypePointer Input %array
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+ %array = OpTypeArray %half %uint_1
+ %ptr = OpTypePointer Input %array
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Input %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Input %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %float = OpTypeFloat 32
+ %struct = OpTypeStruct %float %half
+ %parent = OpTypeStruct %float %struct
+ %ptr = OpTypePointer Input %parent
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %float = OpTypeFloat 32
+ %struct = OpTypeStruct %float %half
+ %parent = OpTypeStruct %float %struct
+ %ptr = OpTypePointer Input %parent
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+ %array = OpTypeArray %struct %uint_1
+ %ptr = OpTypePointer Input %array
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %uint = OpTypeInt 32 0
+ %uint_1 = OpConstant %uint 1
+ %array = OpTypeArray %struct %uint_1
+ %ptr = OpTypePointer Input %array
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %vector = OpTypeVector %half 4
+ %ptr = OpTypePointer Input %vector
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %vector = OpTypeVector %half 4
+ %ptr = OpTypePointer Input %vector
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %vector = OpTypeVector %half 4
+ %matrix = OpTypeMatrix %vector 4
+ %ptr = OpTypePointer Input %matrix
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %vector = OpTypeVector %half 4
+ %matrix = OpTypeMatrix %vector 4
+ %ptr = OpTypePointer Input %matrix
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_IsRemovedWithoutInputPointer) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK-NOT: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer Output %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer Output %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageInputOutput16_RemovedWithoutOutputPointer) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageInputOutput16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK-NOT: OpCapability StorageInputOutput16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StoragePushConstant16_RemainsSimplePointer_Vulkan1_0) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StoragePushConstant16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StoragePushConstant16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer PushConstant %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StoragePushConstant16_RemainsSimplePointer_Vulkan1_1) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StoragePushConstant16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK: OpCapability StoragePushConstant16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer PushConstant %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, StoragePushConstant16_RemovedSimplePointer) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StoragePushConstant16
+ OpExtension "SPV_KHR_16bit_storage"
+; CHECK-NOT: OpCapability StoragePushConstant16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %ptr = OpTypePointer Function %half
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_0) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ OpDecorate %struct BufferBlock
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_1) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ OpDecorate %struct BufferBlock
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniformBufferBlock16_RemovedSimplePointer) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK-NOT: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Function %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_0) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+ static_assert(spv::Capability::StorageUniform16 ==
+ spv::Capability::UniformAndStorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpCapability UniformAndStorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess
+; `-> StorageUniform16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ OpDecorate %struct BufferBlock
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_1) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+ static_assert(spv::Capability::StorageUniform16 ==
+ spv::Capability::UniformAndStorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpCapability UniformAndStorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess
+; `-> StorageUniform16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ OpDecorate %struct BufferBlock
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_0) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+ static_assert(spv::Capability::StorageUniform16 ==
+ spv::Capability::UniformAndStorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpCapability UniformAndStorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK-NOT: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
+; `-> StorageUniform16
+; CHECK: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_0);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_1) {
+ // See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
+ static_assert(spv::Capability::StorageUniformBufferBlock16 ==
+ spv::Capability::StorageBuffer16BitAccess);
+ static_assert(spv::Capability::StorageUniform16 ==
+ spv::Capability::UniformAndStorageBuffer16BitAccess);
+
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability Float16
+ OpCapability StorageBuffer16BitAccess
+ OpCapability UniformAndStorageBuffer16BitAccess
+ OpExtension "SPV_KHR_16bit_storage"
+
+; CHECK-NOT: OpCapability StorageBuffer16BitAccess
+; `-> StorageUniformBufferBlock16
+; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
+; `-> StorageUniform16
+; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
+
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %2 "main"
+ %void = OpTypeVoid
+ %half = OpTypeFloat 16
+ %struct = OpTypeStruct %half
+ %ptr = OpTypePointer Uniform %struct
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ SetTargetEnv(SPV_ENV_VULKAN_1_1);
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, FragmentShaderInterlock_RemovedIfNotUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderPixelInterlock_RemainsWhenOrderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main PixelInterlockOrderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderPixelInterlock_RemainsWhenUnorderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main PixelInterlockUnorderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderSampleInterlock_RemainsWhenOrderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main SampleInterlockOrderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderSampleInterlock_RemainsWhenUnorderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main SampleInterlockUnorderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderShadingRateInterlock_RemainsWhenOrderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main ShadingRateInterlockOrderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ FragmentShaderShadingRateInterlock_RemainsWhenUnorderedIsUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability FragmentShaderPixelInterlockEXT
+ OpCapability FragmentShaderSampleInterlockEXT
+ OpCapability FragmentShaderShadingRateInterlockEXT
+ OpExtension "SPV_EXT_fragment_shader_interlock"
+; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
+; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
+; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT
+; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %main ShadingRateInterlockUnorderedEXT
+ %void = OpTypeVoid
+ %1 = OpTypeFunction %void
+ %2 = OpFunction %void None %1
+ %3 = OpLabel
+ OpBeginInvocationInterlockEXT
+ OpEndInvocationInterlockEXT
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Int64_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Int64
+; CHECK-NOT: OpCapability Int64
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Int64_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Int64
+; CHECK: OpCapability Int64
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %int = OpTypeInt 64 0
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpExtension "SPV_KHR_ray_query"
+; CHECK-NOT: OpCapability RayQueryKHR
+; CHECK-NOT: OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %main "main" %out_var_TEXCOORD1
+ OpSource HLSL 660
+ OpName %out_var_TEXCOORD1 "out.var.TEXCOORD1"
+ OpName %main "main"
+ OpDecorate %out_var_TEXCOORD1 Flat
+ OpDecorate %out_var_TEXCOORD1 Location 0
+ %uint = OpTypeInt 32 0
+ %uint_1234 = OpConstant %uint 1234
+%_ptr_Output_uint = OpTypePointer Output %uint
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+%out_var_TEXCOORD1 = OpVariable %_ptr_Output_uint Output
+ %main = OpFunction %void None %7
+ %8 = OpLabel
+ OpStore %out_var_TEXCOORD1 %uint_1234
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ RayQueryKHR_RemainsWhenAccelerationStructureIsPresent) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpExtension "SPV_KHR_ray_query"
+; CHECK: OpCapability RayQueryKHR
+; CHECK: OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ OpDecorate %var_bvh DescriptorSet 0
+ OpDecorate %var_bvh Binding 0
+ %bvh = OpTypeAccelerationStructureKHR
+ %ptr_bvh = OpTypePointer UniformConstant %bvh
+ %void = OpTypeVoid
+ %20 = OpTypeFunction %void
+ %var_bvh = OpVariable %ptr_bvh UniformConstant
+ %main = OpFunction %void None %20
+ %30 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenRayQueryTypeIsPresent) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpExtension "SPV_KHR_ray_query"
+; CHECK: OpCapability RayQueryKHR
+; CHECK: OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ %query = OpTypeRayQueryKHR
+ %void = OpTypeVoid
+ %20 = OpTypeFunction %void
+ %ptr_query = OpTypePointer Function %query
+ %main = OpFunction %void None %20
+ %30 = OpLabel
+ %var_query = OpVariable %ptr_query Function
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability RayQueryKHR
+ OpExtension "SPV_KHR_ray_query"
+; CHECK: OpCapability RayQueryKHR
+; CHECK: OpExtension "SPV_KHR_ray_query"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ OpDecorate %bvh DescriptorSet 0
+ OpDecorate %bvh Binding 0
+ OpDecorate %output DescriptorSet 0
+ OpDecorate %output Binding 1
+ OpDecorate %_runtimearr_float ArrayStride 4
+ OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0
+ OpDecorate %type_RWStructuredBuffer_float BufferBlock
+ %float = OpTypeFloat 32
+ %float_0 = OpConstant %float 0
+ %int = OpTypeInt 32 1
+ %v3float = OpTypeVector %float 3
+ %12 = OpConstantComposite %v3float %float_0 %float_0 %float_0
+ %int_0 = OpConstant %int 0
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+%accelerationStructureKHR = OpTypeAccelerationStructureKHR
+%_ptr_UniformConstant_accelerationStructureKHR = OpTypePointer UniformConstant %accelerationStructureKHR
+%_runtimearr_float = OpTypeRuntimeArray %float
+%type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float
+%_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float
+ %void = OpTypeVoid
+ %20 = OpTypeFunction %void
+%rayQueryKHR = OpTypeRayQueryKHR
+%_ptr_Function_rayQueryKHR = OpTypePointer Function %rayQueryKHR
+ %bool = OpTypeBool
+%_ptr_Uniform_float = OpTypePointer Uniform %float
+ %bvh = OpVariable %_ptr_UniformConstant_accelerationStructureKHR UniformConstant
+ %output = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform
+ %main = OpFunction %void None %20
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_rayQueryKHR Function
+ %26 = OpLoad %accelerationStructureKHR %bvh
+ OpRayQueryInitializeKHR %25 %26 %uint_0 %uint_0 %12 %float_0 %12 %float_0
+ %27 = OpRayQueryProceedKHR %bool %25
+ %28 = OpRayQueryGetIntersectionTypeKHR %uint %25 %uint_1
+ %29 = OpIEqual %bool %28 %uint_1
+ OpSelectionMerge %30 None
+ OpBranchConditional %29 %31 %30
+ %31 = OpLabel
+ %32 = OpAccessChain %_ptr_Uniform_float %output %int_0 %uint_0
+ OpStore %32 %float_0
+ OpBranch %30
+ %30 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ RayTracingKHR_RemainsWithIntersectionExecutionMode) {
+ const std::string kTest = R"(
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint IntersectionKHR %main "main"
+ OpSource HLSL 660
+ OpName %main "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ RayTracingKHR_RemainsWithClosestHitExecutionMode) {
+ const std::string kTest = R"(
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint ClosestHitKHR %main "main" %a
+ OpSource HLSL 630
+ OpName %Payload "Payload"
+ OpMemberName %Payload 0 "color"
+ OpName %a "a"
+ OpName %main "main"
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %Payload = OpTypeStruct %v4float
+%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %a = OpVariable %ptr_payload IncomingRayPayloadKHR
+ %main = OpFunction %void None %8
+ %9 = OpLabel
+ %10 = OpLoad %Payload %a
+ OpStore %a %10
+ OpReturn
+ OpFunctionEnd
+
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithAnyHitExecutionMode) {
+ const std::string kTest = R"(
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint AnyHitKHR %main "main" %a
+ OpSource HLSL 630
+ OpName %Payload "Payload"
+ OpMemberName %Payload 0 "color"
+ OpName %a "a"
+ OpName %main "main"
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %Payload = OpTypeStruct %v4float
+%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %a = OpVariable %ptr_payload IncomingRayPayloadKHR
+ %main = OpFunction %void None %8
+ %9 = OpLabel
+ %10 = OpLoad %Payload %a
+ OpStore %a %10
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithMissExecutionMode) {
+ const std::string kTest = R"(
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint MissKHR %main "main" %a
+ OpSource HLSL 630
+ OpName %Payload "Payload"
+ OpMemberName %Payload 0 "color"
+ OpName %a "a"
+ OpName %main "main"
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %Payload = OpTypeStruct %v4float
+%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %a = OpVariable %ptr_payload IncomingRayPayloadKHR
+ %main = OpFunction %void None %8
+ %9 = OpLabel
+ %10 = OpLoad %Payload %a
+ OpStore %a %10
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ RayTracingKHR_RemainsWithRayGenerationExecutionMode) {
+ const std::string kTest = R"(
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint RayGenerationKHR %main "main"
+ OpSource HLSL 630
+ OpName %main "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %4 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ RayTracingKHR_RemainsWithCallableExecutionMode) {
+ const std::string kTest = R"(
+; CHECK: OpCapability RayTracingKHR
+; CHECK: OpExtension "SPV_KHR_ray_tracing"
+ OpCapability RayTracingKHR
+ OpExtension "SPV_KHR_ray_tracing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint CallableKHR %main "main" %a
+ OpSource HLSL 660
+ OpName %Payload "Payload"
+ OpMemberName %Payload 0 "data"
+ OpName %a "a"
+ OpName %main "main"
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+ %Payload = OpTypeStruct %v4float
+%ptr_payload = OpTypePointer IncomingCallableDataKHR %Payload
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %a = OpVariable %ptr_payload IncomingCallableDataKHR
+ %main = OpFunction %void None %8
+ %9 = OpLabel
+ %10 = OpLoad %Payload %a
+ OpStore %a %10
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ ImageMSArray_RemainsIfSampledIs2AndArrayedIs1) {
+ const std::string kTest = R"(
+ OpCapability ImageMSArray
+ ; CHECK: OpCapability ImageMSArray
+ OpCapability Shader
+ OpCapability StorageImageMultisample
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v2uint = OpTypeVector %u32 2
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v2uint %uint_1 %uint_2
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10 Sample %uint_2
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfNotUsed) {
+ const std::string kTest = R"(
+ OpCapability Shader
+ OpCapability ImageMSArray
+; CHECK-NOT: OpCapability ImageMSArray
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %out_var_SV_Target
+ OpExecutionMode %main OriginUpperLeft
+ OpSource HLSL 660
+ OpName %out_var_SV_Target "out.var.SV_Target"
+ OpName %main "main"
+ OpDecorate %out_var_SV_Target Location 0
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
+ %main = OpFunction %void None %7
+ %8 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfArrayedIsNot1) {
+ const std::string kTest = R"(
+ OpCapability ImageMSArray
+ ; CHECK-NOT: OpCapability ImageMSArray
+ OpCapability Shader
+ OpCapability StorageImageMultisample
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v2uint = OpTypeVector %u32 2
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v2uint %uint_1 %uint_2
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10 Sample %uint_2
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfSampledNot2) {
+ const std::string kTest = R"(
+ OpCapability ImageMSArray
+ ; CHECK-NOT: OpCapability ImageMSArray
+ OpCapability Shader
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_3 = OpConstant %u32 3
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v3uint = OpTypeVector %u32 3
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Float64_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Float64
+; CHECK-NOT: OpCapability Float64
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Float64_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Float64
+; CHECK: OpCapability Float64
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %float = OpTypeFloat 64
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ ComputeDerivativeGroupQuads_ReamainsWithExecMode) {
+ const std::string kTest = R"(
+ OpCapability ComputeDerivativeGroupQuadsNV
+ OpCapability ComputeDerivativeGroupLinearNV
+; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV
+; CHECK: OpCapability ComputeDerivativeGroupQuadsNV
+; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV
+ OpCapability Shader
+; CHECK: OpExtension "SPV_NV_compute_shader_derivatives"
+ OpExtension "SPV_NV_compute_shader_derivatives"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %1 DerivativeGroupQuadsNV
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ ComputeDerivativeGroupLinear_ReamainsWithExecMode) {
+ const std::string kTest = R"(
+ OpCapability ComputeDerivativeGroupLinearNV
+ OpCapability ComputeDerivativeGroupQuadsNV
+; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV
+; CHECK: OpCapability ComputeDerivativeGroupLinearNV
+; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV
+ OpCapability Shader
+; CHECK: OpExtension "SPV_NV_compute_shader_derivatives"
+ OpExtension "SPV_NV_compute_shader_derivatives"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ OpExecutionMode %1 DerivativeGroupLinearNV
+ %void = OpTypeVoid
+ %float = OpTypeFloat 64
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageImageReadWithoutFormat_RemovedIfUnused) {
+ const std::string kTest = R"(
+ OpCapability StorageImageReadWithoutFormat
+; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %PSMain "PSMain" %out_var
+ OpExecutionMode %PSMain OriginUpperLeft
+ OpDecorate %out_var Location 0
+ %float = OpTypeFloat 32
+ %float4 = OpTypeVector %float 4
+ %float_0 = OpConstant %float 0
+%float4_0000 = OpConstantComposite %float4 %float_0 %float_0 %float_0 %float_0
+ %ptr_float4 = OpTypePointer Output %float4
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %out_var = OpVariable %ptr_float4 Output
+ %PSMain = OpFunction %void None %9
+ %10 = OpLabel
+ OpStore %out_var %float4_0000
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageImageReadWithoutFormat_RemovedIfUnusedOpImageFetch) {
+ const std::string kTest = R"(
+ OpCapability StorageImageReadWithoutFormat
+; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %PSMain "PSMain" %out_var
+ OpExecutionMode %PSMain OriginUpperLeft
+ OpDecorate %out_var Location 0
+ OpDecorate %texture DescriptorSet 0
+ OpDecorate %texture Binding 1
+ %float = OpTypeFloat 32
+ %float4 = OpTypeVector %float 4
+ %int = OpTypeInt 32 1
+ %int2 = OpTypeVector %int 2
+ %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
+ %ptr_image = OpTypePointer UniformConstant %type_image
+ %int_0 = OpConstant %int 0
+ %int2_00 = OpConstantComposite %int2 %int_0 %int_0
+ %ptr_float4 = OpTypePointer Output %float4
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %texture = OpVariable %ptr_image UniformConstant
+ %out_var = OpVariable %ptr_float4 Output
+ %PSMain = OpFunction %void None %9
+ %10 = OpLabel
+ %11 = OpLoad %type_image %texture
+ %12 = OpImageFetch %float4 %11 %int2_00 Lod %int_0
+ OpStore %out_var %12
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageImageReadWithoutFormat_RemainsWhenRequiredWithRead) {
+ const std::string kTest = R"(
+ OpCapability StorageImageReadWithoutFormat
+; CHECK: OpCapability StorageImageReadWithoutFormat
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %PSMain "PSMain" %out_var
+ OpExecutionMode %PSMain OriginUpperLeft
+ OpDecorate %out_var Location 0
+ OpDecorate %texture DescriptorSet 0
+ OpDecorate %texture Binding 1
+ %float = OpTypeFloat 32
+ %float4 = OpTypeVector %float 4
+ %int = OpTypeInt 32 1
+ %int2 = OpTypeVector %int 2
+ %type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
+ %ptr_image = OpTypePointer UniformConstant %type_image
+ %int_0 = OpConstant %int 0
+ %int2_00 = OpConstantComposite %int2 %int_0 %int_0
+ %ptr_float4 = OpTypePointer Output %float4
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %texture = OpVariable %ptr_image UniformConstant
+ %out_var = OpVariable %ptr_float4 Output
+ %PSMain = OpFunction %void None %9
+ %10 = OpLabel
+ %11 = OpLoad %type_image %texture
+ %12 = OpImageRead %float4 %11 %int2_00 Lod %int_0
+ OpStore %out_var %12
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageImageReadWithoutFormat_RemainsWhenRequiredWithSparseRead) {
+ const std::string kTest = R"(
+ OpCapability StorageImageReadWithoutFormat
+; CHECK: OpCapability StorageImageReadWithoutFormat
+ OpCapability SparseResidency
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %PSMain "PSMain"
+ OpExecutionMode %PSMain OriginUpperLeft
+ OpDecorate %texture DescriptorSet 0
+ OpDecorate %texture Binding 1
+ %float = OpTypeFloat 32
+ %float4 = OpTypeVector %float 4
+ %int = OpTypeInt 32 1
+ %int2 = OpTypeVector %int 2
+ %type_image = OpTypeImage %float 2D 2 0 0 2 Unknown
+ %struct = OpTypeStruct %int %float4
+ %ptr_image = OpTypePointer UniformConstant %type_image
+ %int_0 = OpConstant %int 0
+ %int2_00 = OpConstantComposite %int2 %int_0 %int_0
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %texture = OpVariable %ptr_image UniformConstant
+ %PSMain = OpFunction %void None %9
+ %10 = OpLabel
+ %11 = OpLoad %type_image %texture
+ %12 = OpImageSparseRead %struct %11 %int2_00
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ StorageImageReadWithoutFormat_RemovedWithReadOnSubpassData) {
+ const std::string kTest = R"(
+ OpCapability StorageImageReadWithoutFormat
+; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
+ OpCapability InputAttachment
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %PSMain "PSMain" %out_var
+ OpExecutionMode %PSMain OriginUpperLeft
+ OpDecorate %out_var Location 0
+ OpDecorate %texture DescriptorSet 0
+ OpDecorate %texture Binding 1
+ %float = OpTypeFloat 32
+ %float4 = OpTypeVector %float 4
+ %int = OpTypeInt 32 1
+ %int2 = OpTypeVector %int 2
+ %type_image = OpTypeImage %float SubpassData 2 0 0 2 Unknown
+ %ptr_image = OpTypePointer UniformConstant %type_image
+ %int_0 = OpConstant %int 0
+ %int2_00 = OpConstantComposite %int2 %int_0 %int_0
+ %ptr_float4 = OpTypePointer Output %float4
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %texture = OpVariable %ptr_image UniformConstant
+ %out_var = OpVariable %ptr_float4 Output
+ %PSMain = OpFunction %void None %9
+ %10 = OpLabel
+ %11 = OpLoad %type_image %texture
+ %12 = OpImageRead %float4 %11 %int2_00
+ OpStore %out_var %12
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability PhysicalStorageBufferAddresses
+; CHECK-NOT: OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer) {
+ const std::string kTest = R"(
+ OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ %void = OpTypeVoid
+ %int = OpTypeInt 32 0
+ %struct = OpTypeStruct %int
+ OpTypeForwardPointer %ptr PhysicalStorageBuffer
+ %ptr = OpTypePointer PhysicalStorageBuffer %struct
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage) {
+ const std::string kTest = R"(
+ OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ %void = OpTypeVoid
+ %int = OpTypeInt 32 0
+ %struct = OpTypeStruct %int
+ %ptr = OpTypePointer PhysicalStorageBuffer %struct
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ PhysicalStorageBuffer_RemainsWithRestrictDecoration) {
+ const std::string kTest = R"(
+ OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ OpDecorate %var RestrictPointer
+ %void = OpTypeVoid
+ %int = OpTypeInt 32 0
+ %struct = OpTypeStruct %int
+ %ptr = OpTypePointer Function %struct
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ %var = OpVariable %ptr Function
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ PhysicalStorageBuffer_RemainsWithAliasedDecoration) {
+ const std::string kTest = R"(
+ OpCapability PhysicalStorageBufferAddresses
+; CHECK: OpCapability PhysicalStorageBufferAddresses
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ OpDecorate %var AliasedPointer
+ %void = OpTypeVoid
+ %int = OpTypeInt 32 0
+ %struct = OpTypeStruct %int
+ %ptr = OpTypePointer Function %struct
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ %var = OpVariable %ptr Function
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Float16_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Float16
+; CHECK-NOT: OpCapability Float16
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Float16_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Float16
+; CHECK: OpCapability Float16
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %float = OpTypeFloat 16
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Int16_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability Int16
+; CHECK-NOT: OpCapability Int16
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, Int16_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Int16
+; CHECK: OpCapability Int16
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %int = OpTypeInt 16 1
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest, UInt16_RemainsWhenUsed) {
+ const std::string kTest = R"(
+ OpCapability Int16
+; CHECK: OpCapability Int16
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %uint = OpTypeInt 16 0
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ VulkanMemoryModelDeviceScope_RemovedWhenUnused) {
+ const std::string kTest = R"(
+ OpCapability VulkanMemoryModelDeviceScope
+; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %1 "main"
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %1 = OpFunction %void None %3
+ %6 = OpLabel
+ OpReturn
+ OpFunctionEnd;
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ VulkanMemoryModelDeviceScope_RemovedWhenUsedWithGLSL450) {
+ const std::string kTest = R"(
+ OpCapability VulkanMemoryModelDeviceScope
+; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
+ OpCapability Shader
+ OpCapability ShaderClockKHR
+ OpCapability Int64
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %ulong = OpTypeInt 64 0
+ %uint_1 = OpConstant %uint 1
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ %22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
+}
+
+TEST_F(TrimCapabilitiesPassTest,
+ VulkanMemoryModelDeviceScope_RemainsWhenUsedWithVulkan) {
+ const std::string kTest = R"(
+ OpCapability VulkanMemoryModelDeviceScope
+; CHECK: OpCapability VulkanMemoryModelDeviceScope
+ OpCapability Shader
+ OpCapability ShaderClockKHR
+ OpCapability Int64
+ OpExtension "SPV_KHR_shader_clock"
+ OpMemoryModel Logical Vulkan
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 2 4
+ %void = OpTypeVoid
+ %uint = OpTypeInt 32 0
+ %ulong = OpTypeInt 64 0
+ %uint_1 = OpConstant %uint 1
+ %3 = OpTypeFunction %void
+ %main = OpFunction %void None %3
+ %6 = OpLabel
+ %22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
+ OpReturn
+ OpFunctionEnd
+ )";
+ const auto result =
+ SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
+ EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
+}
+
+} // namespace
+} // namespace opt
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp b/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
index 563eb7401..d4d0fef52 100644
--- a/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
+++ b/third_party/SPIRV-Tools/test/opt/type_manager_test.cpp
@@ -171,6 +171,7 @@ std::vector<std::unique_ptr<Type>> GenerateAllTypes() {
types.emplace_back(new NamedBarrier());
types.emplace_back(new AccelerationStructureNV());
types.emplace_back(new CooperativeMatrixNV(f32, 24, 24, 24));
+ types.emplace_back(new CooperativeMatrixKHR(f32, 8, 8, 8, 1002));
types.emplace_back(new RayQueryKHR());
types.emplace_back(new HitObjectNV());
@@ -237,6 +238,8 @@ TEST(TypeManager, TypeStrings) {
%arr_long_constant = OpTypeArray %s32 %long_constant
%arr_spec_const_op = OpTypeArray %s32 %spec_const_op
%cm = OpTypeCooperativeMatrixNV %f64 %id4 %id4 %id4
+ %id2 = OpConstant %u32 2
+ %cmkhr = OpTypeCooperativeMatrixKHR %f64 %id4 %id4 %id4 %id2
)";
std::vector<std::pair<uint32_t, std::string>> type_id_strs = {
@@ -275,6 +278,7 @@ TEST(TypeManager, TypeStrings) {
{37, "[sint32, id(33), words(0,705032704,1)]"},
{38, "[sint32, id(34), words(2,34)]"},
{39, "<float64, 6, 6, 6>"},
+ {41, "<float64, 6, 6, 6, 40>"},
};
std::unique_ptr<IRContext> context =
@@ -938,10 +942,11 @@ OpMemoryModel Logical GLSL450
EXPECT_NE(context, nullptr);
std::vector<std::unique_ptr<Type>> types = GenerateAllTypes();
- uint32_t id = 1u;
+ uint32_t id = 0u;
for (auto& t : types) {
- context->get_type_mgr()->RegisterType(id, *t);
+ context->get_type_mgr()->RegisterType(++id, *t);
EXPECT_EQ(*t, *context->get_type_mgr()->GetType(id));
+ EXPECT_EQ(id, context->get_type_mgr()->GetId(t.get()));
}
types.clear();
@@ -1030,6 +1035,8 @@ TEST(TypeManager, GetTypeInstructionAllTypes) {
; CHECK: [[uint:%\w+]] = OpTypeInt 32 0
; CHECK: [[input_ptr:%\w+]] = OpTypePointer Input [[uint]]
; CHECK: [[uniform_ptr:%\w+]] = OpTypePointer Uniform [[uint]]
+; CHECK: [[uint2:%\w+]] = OpConstant [[uint]] 2
+; CHECK: [[uint8:%\w+]] = OpConstant [[uint]] 8
; CHECK: [[uint24:%\w+]] = OpConstant [[uint]] 24
; CHECK: [[uint42:%\w+]] = OpConstant [[uint]] 42
; CHECK: [[uint100:%\w+]] = OpConstant [[uint]] 100
@@ -1085,6 +1092,7 @@ TEST(TypeManager, GetTypeInstructionAllTypes) {
; CHECK: OpTypeNamedBarrier
; CHECK: OpTypeAccelerationStructureKHR
; CHECK: OpTypeCooperativeMatrixNV [[f32]] [[uint24]] [[uint24]] [[uint24]]
+; CHECK: OpTypeCooperativeMatrixKHR [[f32]] [[uint8]] [[uint8]] [[uint8]] [[uint2]]
; CHECK: OpTypeRayQueryKHR
; CHECK: OpTypeHitObjectNV
OpCapability Shader
@@ -1094,6 +1102,8 @@ OpMemoryModel Logical GLSL450
%uint = OpTypeInt 32 0
%1 = OpTypePointer Input %uint
%2 = OpTypePointer Uniform %uint
+%1002 = OpConstant %uint 2
+%8 = OpConstant %uint 8
%24 = OpConstant %uint 24
%42 = OpConstant %uint 42
%100 = OpConstant %uint 100
@@ -1190,6 +1200,39 @@ OpMemoryModel Logical GLSL450
Match(text, context.get());
}
+// Structures containing circular type references
+// (from https://github.com/KhronosGroup/SPIRV-Tools/issues/5623).
+TEST(TypeManager, CircularPointerToStruct) {
+ const std::string text = R"(
+ OpCapability VariablePointers
+ OpCapability PhysicalStorageBufferAddresses
+ OpCapability Int64
+ OpCapability Shader
+ OpExtension "SPV_KHR_variable_pointers"
+ OpExtension "SPV_KHR_physical_storage_buffer"
+ OpMemoryModel PhysicalStorageBuffer64 GLSL450
+ OpEntryPoint Fragment %1 "main"
+ OpExecutionMode %1 OriginUpperLeft
+ OpExecutionMode %1 DepthReplacing
+ OpDecorate %1200 ArrayStride 24
+ OpMemberDecorate %600 0 Offset 0
+ OpMemberDecorate %800 0 Offset 0
+ OpMemberDecorate %120 0 Offset 16
+ OpTypeForwardPointer %1200 PhysicalStorageBuffer
+ %600 = OpTypeStruct %1200
+ %800 = OpTypeStruct %1200
+ %120 = OpTypeStruct %800
+ %1200 = OpTypePointer PhysicalStorageBuffer %120
+ )";
+
+ std::unique_ptr<IRContext> context =
+ BuildModule(SPV_ENV_UNIVERSAL_1_1, nullptr, text,
+ SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
+ TypeManager manager(nullptr, context.get());
+ uint32_t id = manager.FindPointerToType(600, spv::StorageClass::Function);
+ EXPECT_EQ(id, 1201);
+}
+
} // namespace
} // namespace analysis
} // namespace opt
diff --git a/third_party/SPIRV-Tools/test/scripts/test_compact_ids.py b/third_party/SPIRV-Tools/test/scripts/test_compact_ids.py
index 6ca6e67b2..b1d53870d 100644
--- a/third_party/SPIRV-Tools/test/scripts/test_compact_ids.py
+++ b/third_party/SPIRV-Tools/test/scripts/test_compact_ids.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -47,7 +47,7 @@ def print_usage():
template= \
"""{script} tests correctness of opt pass tools/opt --compact-ids
-USAGE: python {script} [<spirv_files>]
+USAGE: python3 {script} [<spirv_files>]
Requires tools/spirv-dis, tools/spirv-as and tools/spirv-opt to be in path
(call the script from the SPIRV-Tools build output directory).
diff --git a/third_party/SPIRV-Tools/test/text_to_binary.extension_test.cpp b/third_party/SPIRV-Tools/test/text_to_binary.extension_test.cpp
index 55f846660..8e78312e6 100644
--- a/third_party/SPIRV-Tools/test/text_to_binary.extension_test.cpp
+++ b/third_party/SPIRV-Tools/test/text_to_binary.extension_test.cpp
@@ -1247,5 +1247,58 @@ INSTANTIATE_TEST_SUITE_P(
MakeInstruction(spv::Op::OpStencilAttachmentReadEXT, {1, 2, 3})},
})));
+// SPV_KHR_maximal_reconvergence
+
+INSTANTIATE_TEST_SUITE_P(
+ SPV_KHR_maximal_reconvergence, ExtensionRoundTripTest,
+ Combine(
+ Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_0,
+ SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3),
+ ValuesIn(std::vector<AssemblyCase>{
+ {"OpExtension \"SPV_KHR_maximal_reconvergence\"\n",
+ MakeInstruction(spv::Op::OpExtension,
+ MakeVector("SPV_KHR_maximal_reconvergence"))},
+ {"OpExecutionMode %1 MaximallyReconvergesKHR\n",
+ MakeInstruction(
+ spv::Op::OpExecutionMode,
+ {1, (uint32_t)spv::ExecutionMode::MaximallyReconvergesKHR})},
+ })));
+
+// SPV_KHR_float_controls2
+
+INSTANTIATE_TEST_SUITE_P(
+ SPV_KHR_float_controls2, ExtensionRoundTripTest,
+ Combine(
+ Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_5, SPV_ENV_VULKAN_1_0,
+ SPV_ENV_VULKAN_1_1, SPV_ENV_VULKAN_1_2, SPV_ENV_VULKAN_1_3),
+ ValuesIn(std::vector<AssemblyCase>{
+ {"OpExtension \"SPV_KHR_float_controls2\"\n",
+ MakeInstruction(spv::Op::OpExtension,
+ MakeVector("SPV_KHR_float_controls2"))},
+ {"OpCapability FloatControls2\n",
+ MakeInstruction(spv::Op::OpCapability,
+ {(uint32_t)spv::Capability::FloatControls2})},
+ {"OpExecutionMode %1 FPFastMathDefault %2 %3\n",
+ // The operands are: target type, flags constant
+ MakeInstruction(
+ spv::Op::OpExecutionMode,
+ {1, (uint32_t)spv::ExecutionMode::FPFastMathDefault, 2, 3})},
+ {"OpDecorate %1 FPFastMathMode AllowContract\n",
+ MakeInstruction(
+ spv::Op::OpDecorate,
+ {1, (uint32_t)spv::Decoration::FPFastMathMode,
+ (uint32_t)spv::FPFastMathModeMask::AllowContract})},
+ {"OpDecorate %1 FPFastMathMode AllowReassoc\n",
+ MakeInstruction(
+ spv::Op::OpDecorate,
+ {1, (uint32_t)spv::Decoration::FPFastMathMode,
+ (uint32_t)spv::FPFastMathModeMask::AllowReassoc})},
+ {"OpDecorate %1 FPFastMathMode AllowTransform\n",
+ MakeInstruction(
+ spv::Op::OpDecorate,
+ {1, (uint32_t)spv::Decoration::FPFastMathMode,
+ (uint32_t)spv::FPFastMathModeMask::AllowTransform})},
+ })));
+
} // namespace
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/text_to_binary.pipe_storage_test.cpp b/third_party/SPIRV-Tools/test/text_to_binary.pipe_storage_test.cpp
index 2a41d427d..ef899a275 100644
--- a/third_party/SPIRV-Tools/test/text_to_binary.pipe_storage_test.cpp
+++ b/third_party/SPIRV-Tools/test/text_to_binary.pipe_storage_test.cpp
@@ -41,7 +41,7 @@ TEST_F(OpTypePipeStorageTest, ArgumentCount) {
Eq(MakeInstruction(spv::Op::OpTypePipeStorage, {1})));
EXPECT_THAT(CompileFailure("%res = OpTypePipeStorage %1 %2 %3 %4 %5",
SPV_ENV_UNIVERSAL_1_1),
- Eq("'=' expected after result id."));
+ Eq("'=' expected after result id but found '%2'."));
}
using OpConstantPipeStorageTest = spvtest::TextToBinaryTest;
@@ -72,7 +72,7 @@ TEST_F(OpConstantPipeStorageTest, ArgumentCount) {
Eq(MakeInstruction(spv::Op::OpConstantPipeStorage, {1, 2, 3, 4, 5})));
EXPECT_THAT(CompileFailure("%1 = OpConstantPipeStorage %2 3 4 5 %6 %7",
SPV_ENV_UNIVERSAL_1_1),
- Eq("'=' expected after result id."));
+ Eq("'=' expected after result id but found '%7'."));
}
TEST_F(OpConstantPipeStorageTest, ArgumentTypes) {
@@ -118,7 +118,7 @@ TEST_F(OpCreatePipeFromPipeStorageTest, ArgumentCount) {
Eq(MakeInstruction(spv::Op::OpCreatePipeFromPipeStorage, {1, 2, 3})));
EXPECT_THAT(CompileFailure("%1 = OpCreatePipeFromPipeStorage %2 %3 %4 %5",
SPV_ENV_UNIVERSAL_1_1),
- Eq("'=' expected after result id."));
+ Eq("'=' expected after result id but found '%5'."));
}
TEST_F(OpCreatePipeFromPipeStorageTest, ArgumentTypes) {
diff --git a/third_party/SPIRV-Tools/test/tools/CMakeLists.txt b/third_party/SPIRV-Tools/test/tools/CMakeLists.txt
index 4c8989fe3..37fe2b978 100644
--- a/third_party/SPIRV-Tools/test/tools/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/tools/CMakeLists.txt
@@ -13,10 +13,10 @@
# limitations under the License.
add_test(NAME spirv-tools_expect_unittests
- COMMAND ${PYTHON_EXECUTABLE} -m unittest expect_unittest.py
+ COMMAND Python3::Interpreter -m unittest expect_unittest.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_test(NAME spirv-tools_spirv_test_framework_unittests
- COMMAND ${PYTHON_EXECUTABLE} -m unittest spirv_test_framework_unittest.py
+ COMMAND Python3::Interpreter -m unittest spirv_test_framework_unittest.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_spvtools_unittest(
diff --git a/third_party/SPIRV-Tools/test/tools/opt/CMakeLists.txt b/third_party/SPIRV-Tools/test/tools/opt/CMakeLists.txt
index 21aa247f1..966ffbb56 100644
--- a/third_party/SPIRV-Tools/test/tools/opt/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/tools/opt/CMakeLists.txt
@@ -13,9 +13,9 @@
# limitations under the License.
if(NOT ${SPIRV_SKIP_TESTS})
- if(${PYTHONINTERP_FOUND})
+ if(${Python3_Interpreter_FOUND})
add_test(NAME spirv_opt_cli_tools_tests
- COMMAND ${PYTHON_EXECUTABLE}
+ COMMAND Python3::Interpreter
${CMAKE_CURRENT_SOURCE_DIR}/../spirv_test_framework.py
$<TARGET_FILE:spirv-opt> $<TARGET_FILE:spirv-as> $<TARGET_FILE:spirv-dis>
--test-dir ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/third_party/SPIRV-Tools/test/unit_spirv.h b/third_party/SPIRV-Tools/test/unit_spirv.h
index bc9857e69..9e7074cb3 100644
--- a/third_party/SPIRV-Tools/test/unit_spirv.h
+++ b/third_party/SPIRV-Tools/test/unit_spirv.h
@@ -202,9 +202,8 @@ inline std::vector<spv_target_env> AllTargetEnvironments() {
// Returns the capabilities in a CapabilitySet as an ordered vector.
inline std::vector<spv::Capability> ElementsIn(
const spvtools::CapabilitySet& capabilities) {
- std::vector<spv::Capability> result;
- capabilities.ForEach([&result](spv::Capability c) { result.push_back(c); });
- return result;
+ return std::vector<spv::Capability>(capabilities.cbegin(),
+ capabilities.cend());
}
} // namespace spvtest
diff --git a/third_party/SPIRV-Tools/test/val/CMakeLists.txt b/third_party/SPIRV-Tools/test/val/CMakeLists.txt
index 62d93bddc..9d6f6ea6a 100644
--- a/third_party/SPIRV-Tools/test/val/CMakeLists.txt
+++ b/third_party/SPIRV-Tools/test/val/CMakeLists.txt
@@ -46,6 +46,7 @@ add_spvtools_unittest(TARGET val_abcde
val_extension_spv_khr_bit_instructions_test.cpp
val_extension_spv_khr_terminate_invocation_test.cpp
val_extension_spv_khr_subgroup_rotate_test.cpp
+ val_extension_spv_nv_raw_access_chains.cpp
val_ext_inst_test.cpp
val_ext_inst_debug_test.cpp
${VAL_TEST_COMMON_SRCS}
diff --git a/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp b/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
index 9f85a30bb..97dde2df4 100644
--- a/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_annotation_test.cpp
@@ -65,6 +65,171 @@ OpDecorate %var BuiltIn WorkgroupSize
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_F(DecorationTest, FPFastMathModeInvalidMask) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode !524288
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_BINARY, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Invalid floating-point fast math mode operand"));
+}
+
+TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingAllowContract) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode AllowTransform|AllowReassoc
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AllowReassoc and AllowContract must be specified when "
+ "AllowTransform is specified"));
+}
+
+TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingAllowReassoc) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode AllowTransform|AllowContract
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AllowReassoc and AllowContract must be specified when "
+ "AllowTransform is specified"));
+}
+
+TEST_F(DecorationTest, FPFastMathModeAllowTransformMissingContractAndReassoc) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode AllowTransform
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AllowReassoc and AllowContract must be specified when "
+ "AllowTransform is specified"));
+}
+
+TEST_F(DecorationTest, FPFastMathModeAndNoContraction) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode None
+OpDecorate %add NoContraction
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "FPFastMathMode and NoContraction cannot decorate the same target"));
+}
+
+TEST_F(DecorationTest, FPFastMathModeAndNoContraction2) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add NoContraction
+OpDecorate %add FPFastMathMode None
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%undef = OpUndef %float
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%add = OpFAdd %float %undef %undef
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "FPFastMathMode and NoContraction cannot decorate the same target"));
+}
+
using MemberOnlyDecorations = spvtest::ValidateBase<std::string>;
TEST_P(MemberOnlyDecorations, MemberDecoration) {
diff --git a/third_party/SPIRV-Tools/test/val/val_arithmetics_test.cpp b/third_party/SPIRV-Tools/test/val/val_arithmetics_test.cpp
index 631375efb..58ac4423e 100644
--- a/third_party/SPIRV-Tools/test/val/val_arithmetics_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_arithmetics_test.cpp
@@ -1318,7 +1318,7 @@ TEST_F(ValidateArithmetics, CoopMatComponentTypeNotScalarNumeric) {
CompileSuccessfully(GenerateCoopMatCode(types, "").c_str());
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
- HasSubstr("OpTypeCooperativeMatrixNV Component Type <id> "
+ HasSubstr("OpTypeCooperativeMatrix Component Type <id> "
"'4[%bool]' is not a scalar numerical type."));
}
@@ -1331,7 +1331,7 @@ TEST_F(ValidateArithmetics, CoopMatScopeNotConstantInt) {
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
- HasSubstr("OpTypeCooperativeMatrixNV Scope <id> '17[%float_1]' is not a "
+ HasSubstr("OpTypeCooperativeMatrix Scope <id> '17[%float_1]' is not a "
"constant instruction with scalar integer type."));
}
@@ -1344,7 +1344,7 @@ TEST_F(ValidateArithmetics, CoopMatRowsNotConstantInt) {
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
- HasSubstr("OpTypeCooperativeMatrixNV Rows <id> '17[%float_1]' is not a "
+ HasSubstr("OpTypeCooperativeMatrix Rows <id> '17[%float_1]' is not a "
"constant instruction with scalar integer type."));
}
@@ -1357,7 +1357,7 @@ TEST_F(ValidateArithmetics, CoopMatColumnsNotConstantInt) {
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
- HasSubstr("OpTypeCooperativeMatrixNV Cols <id> '17[%float_1]' is not a "
+ HasSubstr("OpTypeCooperativeMatrix Cols <id> '17[%float_1]' is not a "
"constant instruction with scalar integer type."));
}
@@ -1469,6 +1469,149 @@ TEST_F(ValidateArithmetics, SMulExtendedResultTypeMembersNotIdentical) {
"SMulExtended"));
}
+std::string GenerateCoopMatKHRCode(const std::string& extra_types,
+ const std::string& main_body) {
+ const std::string prefix = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u32 = OpTypeInt 32 0
+%s32 = OpTypeInt 32 1
+
+%u32_16 = OpConstant %u32 16
+%u32_4 = OpConstant %u32 4
+%subgroup = OpConstant %u32 3
+%useA = OpConstant %u32 0
+%useB = OpConstant %u32 1
+%useC = OpConstant %u32 2
+
+%f16matA = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA
+%u32matA = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useA
+%s32matA = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useA
+
+%f16matB = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useB
+%u32matB = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useB
+%s32matB = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useB
+
+%f16matC = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useC
+%f32matC = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_16 %u32_16 %useC
+%u32matC = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_16 %u32_16 %useC
+%s32matC = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_16 %u32_16 %useC
+
+%f16_1 = OpConstant %f16 1
+%f32_1 = OpConstant %f32 1
+%u32_1 = OpConstant %u32 1
+%s32_1 = OpConstant %s32 1
+
+%f16mat_A_1 = OpConstantComposite %f16matA %f16_1
+%u32mat_A_1 = OpConstantComposite %u32matA %u32_1
+%s32mat_A_1 = OpConstantComposite %s32matA %s32_1
+
+%f16mat_B_1 = OpConstantComposite %f16matB %f16_1
+%u32mat_B_1 = OpConstantComposite %u32matB %u32_1
+%s32mat_B_1 = OpConstantComposite %s32matB %s32_1
+
+%f16mat_C_1 = OpConstantComposite %f16matC %f16_1
+%u32mat_C_1 = OpConstantComposite %u32matC %u32_1
+%s32mat_C_1 = OpConstantComposite %s32matC %s32_1
+
+)";
+
+ const std::string func_begin = R"(
+%main = OpFunction %void None %func
+%main_entry = OpLabel)";
+
+ const std::string suffix = R"(
+OpReturn
+OpFunctionEnd)";
+
+ return prefix + extra_types + func_begin + main_body + suffix;
+}
+
+TEST_F(ValidateArithmetics, CoopMatKHRSuccess) {
+ const std::string body = R"(
+%val1 = OpFAdd %f16matA %f16mat_A_1 %f16mat_A_1
+%val2 = OpFSub %f16matA %f16mat_A_1 %f16mat_A_1
+%val3 = OpFMul %f16matA %f16mat_A_1 %f16mat_A_1
+%val4 = OpFDiv %f16matA %f16mat_A_1 %f16mat_A_1
+%val5 = OpFNegate %f16matA %f16mat_A_1
+%val6 = OpIAdd %u32matA %u32mat_A_1 %u32mat_A_1
+%val7 = OpISub %u32matA %u32mat_A_1 %u32mat_A_1
+%val8 = OpUDiv %u32matA %u32mat_A_1 %u32mat_A_1
+%val9 = OpIAdd %s32matA %s32mat_A_1 %s32mat_A_1
+%val10 = OpISub %s32matA %s32mat_A_1 %s32mat_A_1
+%val11 = OpSDiv %s32matA %s32mat_A_1 %s32mat_A_1
+%val12 = OpSNegate %s32matA %s32mat_A_1
+%val13 = OpMatrixTimesScalar %f16matA %f16mat_A_1 %f16_1
+%val14 = OpMatrixTimesScalar %u32matA %u32mat_A_1 %u32_1
+%val15 = OpMatrixTimesScalar %s32matA %s32mat_A_1 %s32_1
+%val16 = OpCooperativeMatrixMulAddKHR %f32matC %f16mat_A_1 %f16mat_B_1 %f16mat_C_1
+%val17 = OpCooperativeMatrixMulAddKHR %s32matC %s32mat_A_1 %s32mat_B_1 %s32mat_C_1
+ MatrixASignedComponentsKHR|MatrixBSignedComponentsKHR|MatrixCSignedComponentsKHR|MatrixResultSignedComponentsKHR
+%val18 = OpCooperativeMatrixMulAddKHR %u32matC %u32mat_A_1 %u32mat_B_1 %u32mat_C_1
+)";
+
+ CompileSuccessfully(GenerateCoopMatKHRCode("", body).c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateArithmetics, CoopMatMatrixKHRTimesScalarMismatchFail) {
+ const std::string body = R"(
+%val1 = OpMatrixTimesScalar %f16matA %f16mat_A_1 %f32_1
+)";
+
+ CompileSuccessfully(GenerateCoopMatKHRCode("", body).c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Expected scalar operand type to be equal to the component "
+ "type of the matrix operand: MatrixTimesScalar"));
+}
+
+TEST_F(ValidateArithmetics, CoopMatKHRScopeFail) {
+ const std::string types = R"(
+%workgroup = OpConstant %u32 2
+%mat16x16_wg = OpTypeCooperativeMatrixKHR %f16 %workgroup %u32_16 %u32_16 %useC
+%f16matwg_16x16_1 = OpConstantComposite %mat16x16_wg %f16_1
+)";
+
+ const std::string body = R"(
+%val1 = OpFAdd %f16matA %f16matwg_16x16_1 %f16mat_A_1
+)";
+
+ CompileSuccessfully(GenerateCoopMatKHRCode(types, body).c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Expected scopes of Matrix and Result Type to be identical"));
+}
+
+TEST_F(ValidateArithmetics, CoopMatKHRDimFail) {
+ const std::string types = R"(
+%mat16x4 = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_4 %useC
+%mat16x4_C_1 = OpConstantComposite %mat16x4 %f16_1
+)";
+
+ const std::string body = R"(
+%val1 = OpCooperativeMatrixMulAddKHR %mat16x4 %f16mat_A_1 %f16mat_B_1 %mat16x4_C_1
+)";
+
+ CompileSuccessfully(GenerateCoopMatKHRCode(types, body).c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Cooperative matrix 'N' mismatch: CooperativeMatrixMulAddKHR"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_atomics_test.cpp b/third_party/SPIRV-Tools/test/val/val_atomics_test.cpp
index b266ad666..0f65634a9 100644
--- a/third_party/SPIRV-Tools/test/val/val_atomics_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_atomics_test.cpp
@@ -318,7 +318,8 @@ TEST_F(ValidateAtomics, AtomicAddFloatVulkan) {
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Opcode AtomicFAddEXT requires one of these capabilities: "
- "AtomicFloat32AddEXT AtomicFloat64AddEXT AtomicFloat16AddEXT"));
+ "AtomicFloat16VectorNV AtomicFloat32AddEXT AtomicFloat64AddEXT "
+ "AtomicFloat16AddEXT"));
}
TEST_F(ValidateAtomics, AtomicMinFloatVulkan) {
@@ -331,7 +332,8 @@ TEST_F(ValidateAtomics, AtomicMinFloatVulkan) {
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Opcode AtomicFMinEXT requires one of these capabilities: "
- "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT"));
+ "AtomicFloat16VectorNV AtomicFloat32MinMaxEXT "
+ "AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT"));
}
TEST_F(ValidateAtomics, AtomicMaxFloatVulkan) {
@@ -343,8 +345,10 @@ TEST_F(ValidateAtomics, AtomicMaxFloatVulkan) {
ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
EXPECT_THAT(
getDiagnosticString(),
- HasSubstr("Opcode AtomicFMaxEXT requires one of these capabilities: "
- "AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT AtomicFloat16MinMaxEXT"));
+ HasSubstr(
+ "Opcode AtomicFMaxEXT requires one of these capabilities: "
+ "AtomicFloat16VectorNV AtomicFloat32MinMaxEXT AtomicFloat64MinMaxEXT "
+ "AtomicFloat16MinMaxEXT"));
}
TEST_F(ValidateAtomics, AtomicAddFloatVulkanWrongType1) {
@@ -2713,6 +2717,136 @@ TEST_F(ValidateAtomics, IIncrementBadPointerDataType) {
"value of type Result Type"));
}
+TEST_F(ValidateAtomics, AtomicFloat16VectorSuccess) {
+ const std::string definitions = R"(
+%f16 = OpTypeFloat 16
+%f16vec2 = OpTypeVector %f16 2
+%f16vec4 = OpTypeVector %f16 4
+
+%f16_1 = OpConstant %f16 1
+%f16vec2_1 = OpConstantComposite %f16vec2 %f16_1 %f16_1
+%f16vec4_1 = OpConstantComposite %f16vec4 %f16_1 %f16_1 %f16_1 %f16_1
+
+%f16vec2_ptr = OpTypePointer Workgroup %f16vec2
+%f16vec4_ptr = OpTypePointer Workgroup %f16vec4
+%f16vec2_var = OpVariable %f16vec2_ptr Workgroup
+%f16vec4_var = OpVariable %f16vec4_ptr Workgroup
+)";
+
+ const std::string body = R"(
+%val3 = OpAtomicFMinEXT %f16vec2 %f16vec2_var %device %relaxed %f16vec2_1
+%val4 = OpAtomicFMaxEXT %f16vec2 %f16vec2_var %device %relaxed %f16vec2_1
+%val8 = OpAtomicFAddEXT %f16vec2 %f16vec2_var %device %relaxed %f16vec2_1
+%val9 = OpAtomicExchange %f16vec2 %f16vec2_var %device %relaxed %f16vec2_1
+
+%val11 = OpAtomicFMinEXT %f16vec4 %f16vec4_var %device %relaxed %f16vec4_1
+%val12 = OpAtomicFMaxEXT %f16vec4 %f16vec4_var %device %relaxed %f16vec4_1
+%val18 = OpAtomicFAddEXT %f16vec4 %f16vec4_var %device %relaxed %f16vec4_1
+%val19 = OpAtomicExchange %f16vec4 %f16vec4_var %device %relaxed %f16vec4_1
+
+)";
+
+ CompileSuccessfully(GenerateShaderComputeCode(
+ body,
+ "OpCapability Float16\n"
+ "OpCapability AtomicFloat16VectorNV\n"
+ "OpExtension \"SPV_NV_shader_atomic_fp16_vector\"\n",
+ definitions),
+ SPV_ENV_VULKAN_1_0);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
+static constexpr char Float16Vector3Defs[] = R"(
+%f16 = OpTypeFloat 16
+%f16vec3 = OpTypeVector %f16 3
+
+%f16_1 = OpConstant %f16 1
+%f16vec3_1 = OpConstantComposite %f16vec3 %f16_1 %f16_1 %f16_1
+
+%f16vec3_ptr = OpTypePointer Workgroup %f16vec3
+%f16vec3_var = OpVariable %f16vec3_ptr Workgroup
+)";
+
+TEST_F(ValidateAtomics, AtomicFloat16Vector3MinFail) {
+ const std::string definitions = Float16Vector3Defs;
+
+ const std::string body = R"(
+%val11 = OpAtomicFMinEXT %f16vec3 %f16vec3_var %device %relaxed %f16vec3_1
+)";
+
+ CompileSuccessfully(GenerateShaderComputeCode(
+ body,
+ "OpCapability Float16\n"
+ "OpCapability AtomicFloat16VectorNV\n"
+ "OpExtension \"SPV_NV_shader_atomic_fp16_vector\"\n",
+ definitions),
+ SPV_ENV_VULKAN_1_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("AtomicFMinEXT: expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicFloat16Vector3MaxFail) {
+ const std::string definitions = Float16Vector3Defs;
+
+ const std::string body = R"(
+%val12 = OpAtomicFMaxEXT %f16vec3 %f16vec3_var %device %relaxed %f16vec3_1
+)";
+
+ CompileSuccessfully(GenerateShaderComputeCode(
+ body,
+ "OpCapability Float16\n"
+ "OpCapability AtomicFloat16VectorNV\n"
+ "OpExtension \"SPV_NV_shader_atomic_fp16_vector\"\n",
+ definitions),
+ SPV_ENV_VULKAN_1_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("AtomicFMaxEXT: expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicFloat16Vector3AddFail) {
+ const std::string definitions = Float16Vector3Defs;
+
+ const std::string body = R"(
+%val18 = OpAtomicFAddEXT %f16vec3 %f16vec3_var %device %relaxed %f16vec3_1
+)";
+
+ CompileSuccessfully(GenerateShaderComputeCode(
+ body,
+ "OpCapability Float16\n"
+ "OpCapability AtomicFloat16VectorNV\n"
+ "OpExtension \"SPV_NV_shader_atomic_fp16_vector\"\n",
+ definitions),
+ SPV_ENV_VULKAN_1_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("AtomicFAddEXT: expected Result Type to be float scalar type"));
+}
+
+TEST_F(ValidateAtomics, AtomicFloat16Vector3ExchangeFail) {
+ const std::string definitions = Float16Vector3Defs;
+
+ const std::string body = R"(
+%val19 = OpAtomicExchange %f16vec3 %f16vec3_var %device %relaxed %f16vec3_1
+)";
+
+ CompileSuccessfully(GenerateShaderComputeCode(
+ body,
+ "OpCapability Float16\n"
+ "OpCapability AtomicFloat16VectorNV\n"
+ "OpExtension \"SPV_NV_shader_atomic_fp16_vector\"\n",
+ definitions),
+ SPV_ENV_VULKAN_1_0);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("AtomicExchange: expected Result Type to be integer or "
+ "float scalar type"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_barriers_test.cpp b/third_party/SPIRV-Tools/test/val/val_barriers_test.cpp
index f16090407..ba8ac7d46 100644
--- a/third_party/SPIRV-Tools/test/val/val_barriers_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_barriers_test.cpp
@@ -410,7 +410,7 @@ OpControlBarrier %subgroup %cross_device %none
TEST_F(ValidateBarriers,
OpControlBarrierVulkan1p1WorkgroupNonComputeMemoryFailure) {
const std::string body = R"(
-OpControlBarrier %subgroup %workgroup %acquire
+OpControlBarrier %subgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1);
@@ -427,7 +427,7 @@ OpControlBarrier %subgroup %workgroup %acquire
TEST_F(ValidateBarriers,
OpControlBarrierVulkan1p1WorkgroupNonComputeExecutionFailure) {
const std::string body = R"(
-OpControlBarrier %workgroup %subgroup %acquire
+OpControlBarrier %workgroup %subgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1);
@@ -442,7 +442,7 @@ OpControlBarrier %workgroup %subgroup %acquire
TEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupComputeSuccess) {
const std::string body = R"(
-OpControlBarrier %workgroup %workgroup %acquire
+OpControlBarrier %workgroup %workgroup %acquire_uniform_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_1);
@@ -451,7 +451,7 @@ OpControlBarrier %workgroup %workgroup %acquire
TEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupNonComputeSuccess) {
const std::string body = R"(
-OpControlBarrier %subgroup %subgroup %acquire
+OpControlBarrier %subgroup %subgroup %acquire_uniform_workgroup
)";
CompileSuccessfully(GenerateVulkanVertexShaderCode(body), SPV_ENV_VULKAN_1_1);
@@ -495,15 +495,15 @@ OpControlBarrier %device %device %acquire_and_release_uniform
"AcquireRelease or SequentiallyConsistent"));
}
-// TODO(atgoo@github.com): the corresponding check fails Vulkan CTS,
-// reenable once fixed.
-TEST_F(ValidateBarriers, DISABLED_OpControlBarrierVulkanSubgroupStorageClass) {
+TEST_F(ValidateBarriers, OpControlBarrierVulkanSubgroupStorageClass) {
const std::string body = R"(
OpControlBarrier %workgroup %device %acquire_release_subgroup
)";
CompileSuccessfully(GenerateShaderCode(body), SPV_ENV_VULKAN_1_0);
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpControlBarrier-04650"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
@@ -513,7 +513,7 @@ OpControlBarrier %workgroup %device %acquire_release_subgroup
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionFragment1p1) {
const std::string body = R"(
-OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
+OpControlBarrier %subgroup %subgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
@@ -523,7 +523,7 @@ OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
TEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionFragment1p1) {
const std::string body = R"(
-OpControlBarrier %workgroup %workgroup %acquire_release
+OpControlBarrier %workgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
@@ -541,7 +541,7 @@ OpControlBarrier %workgroup %workgroup %acquire_release
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionFragment1p0) {
const std::string body = R"(
-OpControlBarrier %subgroup %workgroup %acquire_release
+OpControlBarrier %subgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
@@ -556,7 +556,7 @@ OpControlBarrier %subgroup %workgroup %acquire_release
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p1) {
const std::string body = R"(
-OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
+OpControlBarrier %subgroup %subgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"),
@@ -566,7 +566,7 @@ OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
TEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionVertex1p1) {
const std::string body = R"(
-OpControlBarrier %workgroup %workgroup %acquire_release
+OpControlBarrier %workgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"),
@@ -584,7 +584,7 @@ OpControlBarrier %workgroup %workgroup %acquire_release
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p0) {
const std::string body = R"(
-OpControlBarrier %subgroup %workgroup %acquire_release
+OpControlBarrier %subgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Vertex"),
@@ -599,7 +599,7 @@ OpControlBarrier %subgroup %workgroup %acquire_release
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p1) {
const std::string body = R"(
-OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
+OpControlBarrier %subgroup %subgroup %acquire_release_workgroup
)";
CompileSuccessfully(
@@ -610,7 +610,7 @@ OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
TEST_F(ValidateBarriers, OpControlBarrierWorkgroupExecutionGeometry1p1) {
const std::string body = R"(
-OpControlBarrier %workgroup %workgroup %acquire_release
+OpControlBarrier %workgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(
@@ -629,7 +629,7 @@ OpControlBarrier %workgroup %workgroup %acquire_release
TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p0) {
const std::string body = R"(
-OpControlBarrier %subgroup %workgroup %acquire_release
+OpControlBarrier %subgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(
@@ -646,7 +646,7 @@ OpControlBarrier %subgroup %workgroup %acquire_release
TEST_F(ValidateBarriers,
OpControlBarrierSubgroupExecutionTessellationEvaluation1p1) {
const std::string body = R"(
-OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
+OpControlBarrier %subgroup %subgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n",
@@ -658,7 +658,7 @@ OpControlBarrier %subgroup %subgroup %acquire_release_subgroup
TEST_F(ValidateBarriers,
OpControlBarrierWorkgroupExecutionTessellationEvaluation1p1) {
const std::string body = R"(
-OpControlBarrier %workgroup %workgroup %acquire_release
+OpControlBarrier %workgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n",
@@ -678,7 +678,7 @@ OpControlBarrier %workgroup %workgroup %acquire_release
TEST_F(ValidateBarriers,
OpControlBarrierSubgroupExecutionTessellationEvaluation1p0) {
const std::string body = R"(
-OpControlBarrier %subgroup %workgroup %acquire_release
+OpControlBarrier %subgroup %workgroup %acquire_release_workgroup
)";
CompileSuccessfully(GenerateShaderCode(body, "OpCapability Tessellation\n",
diff --git a/third_party/SPIRV-Tools/test/val/val_builtins_test.cpp b/third_party/SPIRV-Tools/test/val/val_builtins_test.cpp
index 4f9fc9763..01049692d 100644
--- a/third_party/SPIRV-Tools/test/val/val_builtins_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_builtins_test.cpp
@@ -4261,6 +4261,260 @@ INSTANTIATE_TEST_SUITE_P(
Values(TestResult(SPV_ERROR_INVALID_DATA,
"needs to be a 3-component 32-bit float vector"))));
+std::string GenerateMeshShadingCode(const std::string& built_in,
+ const std::string& execution_mode,
+ const std::string& body,
+ const std::string& declarations = "") {
+ std::ostringstream ss;
+ ss << R"(
+OpCapability MeshShadingEXT
+OpExtension "SPV_EXT_mesh_shader"
+OpMemoryModel Logical GLSL450
+OpEntryPoint MeshEXT %main "main" %var
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main OutputVertices 1
+OpExecutionMode %main OutputPrimitivesEXT 16
+)";
+ ss << "OpExecutionMode %main " << execution_mode << "\n";
+ ss << "OpDecorate %var BuiltIn " << built_in << "\n";
+
+ ss << R"(
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%int = OpTypeInt 32 1
+%uint = OpTypeInt 32 0
+%v2uint = OpTypeVector %uint 2
+%v3uint = OpTypeVector %uint 3
+
+%int_0 = OpConstant %int 0
+%uint_16 = OpConstant %uint 16
+)";
+
+ ss << declarations;
+
+ ss << R"(
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+)";
+
+ ss << body;
+
+ ss << R"(
+OpReturn
+OpFunctionEnd)";
+ return ss.str();
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveTriangleIndicesEXTSuccess) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v3uint %uint_16
+%array_ptr = OpTypePointer Output %array
+%var = OpVariable %array_ptr Output
+%ptr = OpTypePointer Output %v3uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveTriangleIndicesEXT",
+ "OutputTrianglesEXT", body, declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveTriangleIndicesEXTStorageClass) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v3uint %uint_16
+%array_ptr = OpTypePointer Input %array
+%var = OpVariable %array_ptr Input
+%ptr = OpTypePointer Input %v3uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveTriangleIndicesEXT",
+ "OutputTrianglesEXT", body, declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-PrimitiveTriangleIndicesEXT-"
+ "PrimitiveTriangleIndicesEXT-07055"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveTriangleIndicesEXTVectorSize) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v2uint %uint_16
+%array_ptr = OpTypePointer Output %array
+%var = OpVariable %array_ptr Output
+%ptr = OpTypePointer Output %v2uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveTriangleIndicesEXT",
+ "OutputTrianglesEXT", body, declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-PrimitiveTriangleIndicesEXT-"
+ "PrimitiveTriangleIndicesEXT-07056"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveTriangleIndicesEXTNonArray) {
+ const std::string declarations = R"(
+%ptr = OpTypePointer Output %v3uint
+%var = OpVariable %ptr Output
+)";
+ const std::string body = R"(
+%load = OpLoad %v3uint %var
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveTriangleIndicesEXT",
+ "OutputTrianglesEXT", body, declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-PrimitiveTriangleIndicesEXT-"
+ "PrimitiveTriangleIndicesEXT-07056"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveLineIndicesEXTSuccess) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v2uint %uint_16
+%array_ptr = OpTypePointer Output %array
+%var = OpVariable %array_ptr Output
+%ptr = OpTypePointer Output %v2uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveLineIndicesEXT", "OutputLinesEXT", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveLineIndicesEXTStorageClass) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v2uint %uint_16
+%array_ptr = OpTypePointer Input %array
+%var = OpVariable %array_ptr Input
+%ptr = OpTypePointer Input %v2uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveLineIndicesEXT", "OutputLinesEXT", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ AnyVUID("VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07049"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitiveLineIndicesEXTType) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v3uint %uint_16
+%array_ptr = OpTypePointer Input %array
+%var = OpVariable %array_ptr Input
+%ptr = OpTypePointer Input %v3uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitiveLineIndicesEXT", "OutputLinesEXT", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ AnyVUID("VUID-PrimitiveLineIndicesEXT-PrimitiveLineIndicesEXT-07050"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitivePointIndicesEXTSuccess) {
+ const std::string declarations = R"(
+%array = OpTypeArray %uint %uint_16
+%array_ptr = OpTypePointer Output %array
+%var = OpVariable %array_ptr Output
+%ptr = OpTypePointer Output %uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitivePointIndicesEXT", "OutputPoints", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitivePointIndicesEXTStorageClass) {
+ const std::string declarations = R"(
+%array = OpTypeArray %uint %uint_16
+%array_ptr = OpTypePointer Input %array
+%var = OpVariable %array_ptr Input
+%ptr = OpTypePointer Input %uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitivePointIndicesEXT", "OutputPoints", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ AnyVUID("VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07043"));
+}
+
+TEST_F(ValidateBuiltIns, VulkanPrimitivePointIndicesEXTType) {
+ const std::string declarations = R"(
+%array = OpTypeArray %v3uint %uint_16
+%array_ptr = OpTypePointer Output %array
+%var = OpVariable %array_ptr Output
+%ptr = OpTypePointer Output %v3uint
+)";
+ const std::string body = R"(
+%access = OpAccessChain %ptr %var %int_0
+)";
+
+ CompileSuccessfully(
+ GenerateMeshShadingCode("PrimitivePointIndicesEXT", "OutputPoints", body,
+ declarations)
+ .c_str(),
+ SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ AnyVUID("VUID-PrimitivePointIndicesEXT-PrimitivePointIndicesEXT-07044"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_cfg_test.cpp b/third_party/SPIRV-Tools/test/val/val_cfg_test.cpp
index 3953057e1..233aee645 100644
--- a/third_party/SPIRV-Tools/test/val/val_cfg_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_cfg_test.cpp
@@ -4803,6 +4803,321 @@ TEST_F(ValidateCFG, BadSwitch) {
"via a structured exit"));
}
+TEST_F(ValidateCFG,
+ MaximalReconvergenceBranchConditionalSameTargetNotInCallTree) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+OpBranchConditional %cond %func_exit %func_exit
+%func_exit = OpLabel
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceBranchConditionalSameTargetInCallTree) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+OpBranchConditional %cond %func_exit %func_exit
+%func_exit = OpLabel
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("In entry points using the MaximallyReconvergesKHR "
+ "execution mode, True "
+ "Label and False Label must be different labels"));
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceEarlyReconvergenceNotInCallTree) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+OpSelectionMerge %func_exit None
+OpBranchConditional %cond %then %else
+%then = OpLabel
+OpBranch %merge
+%else = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpBranch %func_exit
+%func_exit = OpLabel
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceEarlyReconvergenceInCallTree) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+OpSelectionMerge %func_exit None
+OpBranchConditional %cond %then %else
+%then = OpLabel
+OpBranch %merge
+%else = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpBranch %func_exit
+%func_exit = OpLabel
+OpReturn
+OpFunctionEnd
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_ERROR_INVALID_CFG, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "In entry points using the MaximallyReconvergesKHR execution mode, "
+ "this basic block must not have multiple unique predecessors"));
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceLoopMultiplePredsOk) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpBranch %loop
+%loop = OpLabel
+OpLoopMerge %merge %loop None
+OpBranchConditional %cond %loop %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceLoopMultiplePredsOk2) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpBranch %loop
+%loop = OpLabel
+OpLoopMerge %merge %cont None
+OpBranch %body
+%body = OpLabel
+OpBranch %cont
+%cont = OpLabel
+OpBranchConditional %cond %loop %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceSelectionMergeMultiplePredsOk) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpSelectionMerge %merge None
+OpBranchConditional %cond %then %else
+%then = OpLabel
+OpBranch %merge
+%else = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceSelectionMergeMultiplePredsOk2) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+OpName %merge "merge"
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpSelectionMerge %merge None
+OpBranchConditional %cond %then %else
+%then = OpLabel
+OpBranch %merge
+%else = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceLoopMergeMultiplePredsOk) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpBranch %loop
+%loop = OpLabel
+OpLoopMerge %merge %continue None
+OpBranchConditional %cond %merge %continue
+%continue = OpLabel
+OpBranchConditional %cond %loop %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateCFG, MaximalReconvergenceCaseFallthroughMultiplePredsOk) {
+ const std::string text = R"(
+OpCapability Shader
+OpExtension "SPV_KHR_maximal_reconvergence"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%bool = OpTypeBool
+%cond = OpUndef %bool
+%int = OpTypeInt 32 0
+%val = OpUndef %int
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%main_entry = OpLabel
+OpSelectionMerge %merge None
+OpSwitch %val %merge 0 %case1 1 %case2
+%case1 = OpLabel
+OpBranch %case2
+%case2 = OpLabel
+OpBranch %merge
+%merge = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_composites_test.cpp b/third_party/SPIRV-Tools/test/val/val_composites_test.cpp
index 0fd1ed652..6e0d7c03c 100644
--- a/third_party/SPIRV-Tools/test/val/val_composites_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_composites_test.cpp
@@ -1486,8 +1486,7 @@ OpFunctionEnd
}
TEST_F(ValidateComposites, CoopMatConstantCompositeMismatchFail) {
- const std::string body =
- R"(
+ const std::string body = R"(
OpCapability Shader
OpCapability Float16
OpCapability CooperativeMatrixNV
@@ -1525,8 +1524,7 @@ OpFunctionEnd)";
}
TEST_F(ValidateComposites, CoopMatCompositeConstructMismatchFail) {
- const std::string body =
- R"(
+ const std::string body = R"(
OpCapability Shader
OpCapability Float16
OpCapability CooperativeMatrixNV
@@ -1562,6 +1560,86 @@ OpFunctionEnd)";
HasSubstr("Expected Constituent type to be equal to the component type"));
}
+TEST_F(ValidateComposites, CoopMatKHRConstantCompositeMismatchFail) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u32 = OpTypeInt 32 0
+
+%u32_16 = OpConstant %u32 16
+%useA = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA
+
+%f32_1 = OpConstant %f32 1
+
+%f16mat_1 = OpConstantComposite %f16mat %f32_1
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "OpConstantComposite Constituent <id> '12[%float_1]' type "
+ "does not match the Result Type <id> '11[%11]'s component type."));
+}
+
+TEST_F(ValidateComposites, CoopMatKHRCompositeConstructMismatchFail) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u32 = OpTypeInt 32 0
+
+%u32_16 = OpConstant %u32 16
+%useA = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_16 %u32_16 %useA
+
+%f32_1 = OpConstant %f32 1
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%f16mat_1 = OpCompositeConstruct %f16mat %f32_1
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Expected Constituent type to be equal to the component type"));
+}
+
TEST_F(ValidateComposites, ExtractDynamicLabelIndex) {
const std::string spirv = R"(
OpCapability Shader
diff --git a/third_party/SPIRV-Tools/test/val/val_conversion_test.cpp b/third_party/SPIRV-Tools/test/val/val_conversion_test.cpp
index 1f8c4265b..0128aa1f2 100644
--- a/third_party/SPIRV-Tools/test/val/val_conversion_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_conversion_test.cpp
@@ -1149,8 +1149,7 @@ OpFunctionEnd)";
}
TEST_F(ValidateConversion, CoopMatConversionShapesMismatchPass) {
- const std::string body =
- R"(
+ const std::string body = R"(
OpCapability Shader
OpCapability Float16
OpCapability Int16
@@ -1191,6 +1190,179 @@ OpFunctionEnd)";
ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_F(ValidateConversion, CoopMatKHRConversionSuccess) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability Int16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u16 = OpTypeInt 16 0
+%u32 = OpTypeInt 32 0
+%s16 = OpTypeInt 16 1
+%s32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%use_A = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+%f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_A
+%u16mat = OpTypeCooperativeMatrixKHR %u16 %subgroup %u32_8 %u32_8 %use_A
+%u32mat = OpTypeCooperativeMatrixKHR %u32 %subgroup %u32_8 %u32_8 %use_A
+%s16mat = OpTypeCooperativeMatrixKHR %s16 %subgroup %u32_8 %u32_8 %use_A
+%s32mat = OpTypeCooperativeMatrixKHR %s32 %subgroup %u32_8 %u32_8 %use_A
+
+%f16_1 = OpConstant %f16 1
+%f32_1 = OpConstant %f32 1
+%u16_1 = OpConstant %u16 1
+%u32_1 = OpConstant %u32 1
+%s16_1 = OpConstant %s16 1
+%s32_1 = OpConstant %s32 1
+
+%f16mat_1 = OpConstantComposite %f16mat %f16_1
+%f32mat_1 = OpConstantComposite %f32mat %f32_1
+%u16mat_1 = OpConstantComposite %u16mat %u16_1
+%u32mat_1 = OpConstantComposite %u32mat %u32_1
+%s16mat_1 = OpConstantComposite %s16mat %s16_1
+%s32mat_1 = OpConstantComposite %s32mat %s32_1
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%val11 = OpConvertFToU %u16mat %f16mat_1
+%val12 = OpConvertFToU %u32mat %f16mat_1
+%val13 = OpConvertFToS %s16mat %f16mat_1
+%val14 = OpConvertFToS %s32mat %f16mat_1
+%val15 = OpFConvert %f32mat %f16mat_1
+
+%val21 = OpConvertFToU %u16mat %f32mat_1
+%val22 = OpConvertFToU %u32mat %f32mat_1
+%val23 = OpConvertFToS %s16mat %f32mat_1
+%val24 = OpConvertFToS %s32mat %f32mat_1
+%val25 = OpFConvert %f16mat %f32mat_1
+
+%val31 = OpConvertUToF %f16mat %u16mat_1
+%val32 = OpConvertUToF %f32mat %u16mat_1
+%val33 = OpUConvert %u32mat %u16mat_1
+%val34 = OpSConvert %s32mat %u16mat_1
+
+%val41 = OpConvertSToF %f16mat %s16mat_1
+%val42 = OpConvertSToF %f32mat %s16mat_1
+%val43 = OpUConvert %u32mat %s16mat_1
+%val44 = OpSConvert %s32mat %s16mat_1
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateConversion, CoopMatKHRConversionUseMismatchFail) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability Int16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u16 = OpTypeInt 16 0
+%u32 = OpTypeInt 32 0
+%s16 = OpTypeInt 16 1
+%s32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%u32_4 = OpConstant %u32 4
+%subgroup = OpConstant %u32 3
+%use_A = OpConstant %u32 0
+%use_B = OpConstant %u32 1
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+%f32mat = OpTypeCooperativeMatrixKHR %f32 %subgroup %u32_8 %u32_8 %use_B
+
+%f16_1 = OpConstant %f16 1
+
+%f16mat_1 = OpConstantComposite %f16mat %f16_1
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%val1 = OpFConvert %f32mat %f16mat_1
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Expected Use of Matrix type and Result Type to be identical"));
+}
+
+TEST_F(ValidateConversion, CoopMatKHRConversionScopeMismatchFail) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability Int16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%bool = OpTypeBool
+%f16 = OpTypeFloat 16
+%f32 = OpTypeFloat 32
+%u16 = OpTypeInt 16 0
+%u32 = OpTypeInt 32 0
+%s16 = OpTypeInt 16 1
+%s32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%u32_4 = OpConstant %u32 4
+%subgroup = OpConstant %u32 3
+%workgroup = OpConstant %u32 2
+%use_A = OpConstant %u32 0
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+%f32mat = OpTypeCooperativeMatrixKHR %f32 %workgroup %u32_8 %u32_8 %use_A
+
+%f16_1 = OpConstant %f16 1
+
+%f16mat_1 = OpConstantComposite %f16mat %f16_1
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%val1 = OpFConvert %f32mat %f16mat_1
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Expected scopes of Matrix and Result Type to be identical"));
+}
+
TEST_F(ValidateConversion, BitcastSuccess) {
const std::string body = R"(
%ptr = OpVariable %f32ptr_func Function
diff --git a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
index be16abae9..ba0e95976 100644
--- a/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_decoration_test.cpp
@@ -3209,6 +3209,48 @@ TEST_F(ValidateDecorations,
"statically used per shader entry point."));
}
+TEST_F(ValidateDecorations,
+ VulkanMultiplePushConstantsSingleEntryPointInterfaceBad) {
+ std::string spirv = R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Vertex %func1 "func1" %pc1 %pc2
+ OpDecorate %struct Block
+ OpMemberDecorate %struct 0 Offset 0
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %int = OpTypeInt 32 0
+ %int_0 = OpConstant %int 0
+ %struct = OpTypeStruct %float
+ %ptr = OpTypePointer PushConstant %struct
+%ptr_float = OpTypePointer PushConstant %float
+ %pc1 = OpVariable %ptr PushConstant
+ %pc2 = OpVariable %ptr PushConstant
+ %func1 = OpFunction %void None %voidfn
+ %label1 = OpLabel
+ %access1 = OpAccessChain %ptr_float %pc1 %int_0
+ %load1 = OpLoad %float %access1
+ OpReturn
+ OpFunctionEnd
+ %func2 = OpFunction %void None %voidfn
+ %label2 = OpLabel
+ %access2 = OpAccessChain %ptr_float %pc2 %int_0
+ %load2 = OpLoad %float %access2
+ OpReturn
+ OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpVariable-06673"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Entry-point has more than one variable with the "
+ "PushConstant storage class in the interface"));
+}
+
TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
std::string spirv = R"(
OpCapability Shader
@@ -8003,6 +8045,7 @@ TEST_F(ValidateDecorations, WorkgroupBlockVariableWith16BitType) {
OpCapability Shader
OpCapability Float16
OpCapability Int16
+ OpCapability WorkgroupMemoryExplicitLayoutKHR
OpCapability WorkgroupMemoryExplicitLayout16BitAccessKHR
OpExtension "SPV_KHR_workgroup_memory_explicit_layout"
OpMemoryModel Logical GLSL450
@@ -8265,6 +8308,37 @@ TEST_F(ValidateDecorations, WorkgroupSingleBlockVariableBadLayout) {
"member 0 at offset 1 is not aligned to 4"));
}
+TEST_F(ValidateDecorations, WorkgroupBlockNoCapability) {
+ std::string spirv = R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main" %_
+ OpExecutionMode %main LocalSize 1 1 1
+ OpMemberDecorate %struct 0 Offset 0
+ OpMemberDecorate %struct 1 Offset 4
+ OpDecorate %struct Block
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %int = OpTypeInt 32 1
+ %struct = OpTypeStruct %int %int
+%ptr_workgroup = OpTypePointer Workgroup %struct
+ %_ = OpVariable %ptr_workgroup Workgroup
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_BINARY,
+ ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1_SPIRV_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Workgroup Storage Class variables can't be decorated with Block "
+ "unless declaring the WorkgroupMemoryExplicitLayoutKHR capability"));
+}
+
TEST_F(ValidateDecorations, BadMatrixStrideUniform) {
const std::string spirv = R"(
OpCapability Shader
@@ -9252,6 +9326,124 @@ OpFunctionEnd
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
}
+TEST_F(ValidateDecorations, PhysicalStorageBufferWithOffset) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Int64
+OpCapability PhysicalStorageBufferAddresses
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint GLCompute %main "main" %pc
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %pc_block Block
+OpMemberDecorate %pc_block 0 Offset 0
+OpMemberDecorate %pssbo_struct 0 Offset 0
+%void = OpTypeVoid
+%long = OpTypeInt 64 0
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%pc_block = OpTypeStruct %long
+%pc_block_ptr = OpTypePointer PushConstant %pc_block
+%pc_long_ptr = OpTypePointer PushConstant %long
+%pc = OpVariable %pc_block_ptr PushConstant
+%pssbo_struct = OpTypeStruct %float
+%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
+%addr = OpLoad %long %pc_gep
+%ptr = OpConvertUToPtr %pssbo_ptr %addr
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
+}
+
+TEST_F(ValidateDecorations, PhysicalStorageBufferMissingOffset) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Int64
+OpCapability PhysicalStorageBufferAddresses
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint GLCompute %main "main" %pc
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %pc_block Block
+OpMemberDecorate %pc_block 0 Offset 0
+%void = OpTypeVoid
+%long = OpTypeInt 64 0
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%pc_block = OpTypeStruct %long
+%pc_block_ptr = OpTypePointer PushConstant %pc_block
+%pc_long_ptr = OpTypePointer PushConstant %long
+%pc = OpVariable %pc_block_ptr PushConstant
+%pssbo_struct = OpTypeStruct %float
+%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_struct
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
+%addr = OpLoad %long %pc_gep
+%ptr = OpConvertUToPtr %pssbo_ptr %addr
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("decorated as Block for variable in PhysicalStorageBuffer "
+ "storage class must follow relaxed storage buffer layout "
+ "rules: member 0 is missing an Offset decoration"));
+}
+
+TEST_F(ValidateDecorations, PhysicalStorageBufferMissingArrayStride) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Int64
+OpCapability PhysicalStorageBufferAddresses
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint GLCompute %main "main" %pc
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %pc_block Block
+OpMemberDecorate %pc_block 0 Offset 0
+%void = OpTypeVoid
+%long = OpTypeInt 64 0
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_4 = OpConstant %int 4
+%pc_block = OpTypeStruct %long
+%pc_block_ptr = OpTypePointer PushConstant %pc_block
+%pc_long_ptr = OpTypePointer PushConstant %long
+%pc = OpVariable %pc_block_ptr PushConstant
+%pssbo_array = OpTypeArray %float %int_4
+%pssbo_ptr = OpTypePointer PhysicalStorageBuffer %pssbo_array
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%pc_gep = OpAccessChain %pc_long_ptr %pc %int_0
+%addr = OpLoad %long %pc_gep
+%ptr = OpConvertUToPtr %pssbo_ptr %addr
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "decorated as Block for variable in PhysicalStorageBuffer storage "
+ "class must follow relaxed storage buffer layout rules: member 0 "
+ "contains an array with stride 0, but with an element size of 4"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp b/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
index 554e78b08..8f0da42d5 100644
--- a/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_ext_inst_debug_test.cpp
@@ -1012,9 +1012,9 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypePointerFail) {
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, size_const, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("expected operand Base Type must be a result id of "
- "DebugTypeBasic"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("expected operand Base Type is not a valid debug type"));
}
TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifier) {
@@ -1077,9 +1077,9 @@ TEST_F(ValidateOpenCL100DebugInfo, DebugTypeQualifierFail) {
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, size_const, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("expected operand Base Type must be a result id of "
- "DebugTypeBasic"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("expected operand Base Type is not a valid debug type"));
}
TEST_F(ValidateVulkan100DebugInfo, DebugTypeQualifier) {
const std::string src = R"(
@@ -1147,9 +1147,9 @@ OpExtension "SPV_KHR_non_semantic_info"
CompileSuccessfully(GenerateShaderCodeForDebugInfo(
src, constants, dbg_inst_header, "", extension, "Vertex"));
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("expected operand Base Type must be a result id of "
- "DebugTypeBasic"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("expected operand Base Type is not a valid debug type"));
}
TEST_F(ValidateOpenCL100DebugInfo, DebugTypeArray) {
diff --git a/third_party/SPIRV-Tools/test/val/val_extension_spv_nv_raw_access_chains.cpp b/third_party/SPIRV-Tools/test/val/val_extension_spv_nv_raw_access_chains.cpp
new file mode 100644
index 000000000..f06d7cd4b
--- /dev/null
+++ b/third_party/SPIRV-Tools/test/val/val_extension_spv_nv_raw_access_chains.cpp
@@ -0,0 +1,510 @@
+// Copyright (c) 2024 The Khronos Group Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <string>
+
+#include "gmock/gmock.h"
+#include "source/spirv_target_env.h"
+#include "test/unit_spirv.h"
+#include "test/val/val_fixtures.h"
+
+namespace spvtools {
+namespace val {
+namespace {
+
+using ::testing::HasSubstr;
+
+using ValidateSpvNVRawAccessChains = spvtest::ValidateBase<bool>;
+
+TEST_F(ValidateSpvNVRawAccessChains, Valid) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, NoCapability) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_CAPABILITY, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("requires one of these capabilities: RawAccessChainsNV"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, NoExtension) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("requires one of these extensions: SPV_NV_raw_access_chains"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, ReturnTypeNotPointer) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %int %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("must be OpTypePointer. Found OpTypeInt"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, Workgroup) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer Workgroup %intStruct
+ %ssbo = OpVariable %intStructPtr Workgroup
+ %intPtr = OpTypePointer Workgroup %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("must point to a storage class of"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, ReturnTypeArray) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %int_1 = OpConstant %int 1
+ %intArray = OpTypeArray %int %int_1
+ %intArrayPtr = OpTypePointer StorageBuffer %intArray
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intArrayPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerComponentNV
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("must not point to"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, VariableStride) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %stride = OpIAdd %int %int_0 %int_0
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %stride %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("must be OpConstant"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, RobustnessPerElementZeroStride) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_0 %int_0 %int_0 RobustnessPerElementNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Stride must not be zero when per-element robustness is used"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, BothRobustness) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %int_0 RobustnessPerElementNV|RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Per-component robustness and per-element robustness "
+ "are mutually exclusive"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, StrideFloat) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %float = OpTypeFloat 32
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %float_16 = OpConstant %float 16
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %float_16 %int_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("must be OpTypeInt"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, IndexType) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpCapability Int64
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %long = OpTypeInt 64 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+ %long_0 = OpConstant %long 0
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %long_0 %int_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("The integer width of Index"));
+}
+
+TEST_F(ValidateSpvNVRawAccessChains, OffsetType) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability RawAccessChainsNV
+ OpCapability Int64
+ OpExtension "SPV_KHR_storage_buffer_storage_class"
+ OpExtension "SPV_NV_raw_access_chains"
+ OpMemoryModel Logical GLSL450
+
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+
+ OpDecorate %intStruct Block
+ OpMemberDecorate %intStruct 0 Offset 0
+ OpDecorate %ssbo DescriptorSet 0
+ OpDecorate %ssbo Binding 0
+
+ %int = OpTypeInt 32 1
+ %long = OpTypeInt 64 1
+ %void = OpTypeVoid
+ %mainFunctionType = OpTypeFunction %void
+ %intStruct = OpTypeStruct %int
+ %intStructPtr = OpTypePointer StorageBuffer %intStruct
+ %ssbo = OpVariable %intStructPtr StorageBuffer
+ %intPtr = OpTypePointer StorageBuffer %int
+
+ %int_0 = OpConstant %int 0
+ %int_16 = OpConstant %int 16
+ %long_0 = OpConstant %long 0
+
+ %main = OpFunction %void None %mainFunctionType
+ %label = OpLabel
+ %rawChain = OpRawAccessChainNV %intPtr %ssbo %int_16 %int_0 %long_0 RobustnessPerComponentNV
+ %unused = OpLoad %int %rawChain
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("The integer width of Offset"));
+}
+
+} // namespace
+} // namespace val
+} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_extensions_test.cpp b/third_party/SPIRV-Tools/test/val/val_extensions_test.cpp
index 0ab8c6e3c..932bbee8f 100644
--- a/third_party/SPIRV-Tools/test/val/val_extensions_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_extensions_test.cpp
@@ -131,6 +131,214 @@ TEST_F(ValidateExtensionCapabilities, DeclCapabilityFailure) {
EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_KHR_device_group"));
}
+TEST_F(ValidateExtensionCapabilities,
+ DeclCapabilityFailureBlockMatchWIndowSAD) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %v_texcoord %fragColor %target_samp %ref_samp
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpSourceExtension "GL_QCOM_image_processing"
+ OpSourceExtension "GL_QCOM_image_processing2"
+ OpName %main "main"
+ OpName %tgt_coords "tgt_coords"
+ OpName %v_texcoord "v_texcoord"
+ OpName %ref_coords "ref_coords"
+ OpName %blockSize "blockSize"
+ OpName %fragColor "fragColor"
+ OpName %target_samp "target_samp"
+ OpName %ref_samp "ref_samp"
+ OpDecorate %v_texcoord Location 0
+ OpDecorate %fragColor Location 0
+ OpDecorate %target_samp DescriptorSet 0
+ OpDecorate %target_samp Binding 4
+ OpDecorate %ref_samp DescriptorSet 0
+ OpDecorate %ref_samp Binding 5
+ OpDecorate %target_samp BlockMatchTextureQCOM
+ OpDecorate %target_samp BlockMatchSamplerQCOM
+ OpDecorate %ref_samp BlockMatchTextureQCOM
+ OpDecorate %ref_samp BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %v_texcoord = OpVariable %_ptr_Input_v4float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %39 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %fragColor = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %43 = OpTypeSampledImage %42
+%_ptr_UniformConstant_43 = OpTypePointer UniformConstant %43
+%target_samp = OpVariable %_ptr_UniformConstant_43 UniformConstant
+ %ref_samp = OpVariable %_ptr_UniformConstant_43 UniformConstant
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %tgt_coords = OpVariable %_ptr_Function_v2uint Function
+ %ref_coords = OpVariable %_ptr_Function_v2uint Function
+ %blockSize = OpVariable %_ptr_Function_v2uint Function
+ %16 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_0
+ %17 = OpLoad %float %16
+ %18 = OpConvertFToU %uint %17
+ %20 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %20 %18
+ %22 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_1
+ %23 = OpLoad %float %22
+ %24 = OpConvertFToU %uint %23
+ %25 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %25 %24
+ %28 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_2
+ %29 = OpLoad %float %28
+ %30 = OpConvertFToU %uint %29
+ %31 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_0
+ OpStore %31 %30
+ %33 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_3
+ %34 = OpLoad %float %33
+ %35 = OpConvertFToU %uint %34
+ %36 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_1
+ OpStore %36 %35
+ OpStore %blockSize %39
+ %46 = OpLoad %43 %target_samp
+ %47 = OpLoad %v2uint %tgt_coords
+ %49 = OpLoad %43 %ref_samp
+ %50 = OpLoad %v2uint %ref_coords
+ %51 = OpLoad %v2uint %blockSize
+ %52 = OpImageBlockMatchWindowSADQCOM %v4float %46 %47 %49 %50 %51
+ OpStore %fragColor %52
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("2nd operand of Decorate"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("requires one of these extensions"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_QCOM_image_processing"));
+}
+
+TEST_F(ValidateExtensionCapabilities,
+ DeclCapabilityFailureBlockMatchWIndowSSD) {
+ const std::string str = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %v_texcoord %fragColor %tex2D_src1 %samp %tex2D_src2
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpSourceExtension "GL_QCOM_image_processing"
+ OpSourceExtension "GL_QCOM_image_processing2"
+ OpName %main "main"
+ OpName %tgt_coords "tgt_coords"
+ OpName %v_texcoord "v_texcoord"
+ OpName %ref_coords "ref_coords"
+ OpName %blockSize "blockSize"
+ OpName %fragColor "fragColor"
+ OpName %tex2D_src1 "tex2D_src1"
+ OpName %samp "samp"
+ OpName %tex2D_src2 "tex2D_src2"
+ OpDecorate %v_texcoord Location 0
+ OpDecorate %fragColor Location 0
+ OpDecorate %tex2D_src1 DescriptorSet 0
+ OpDecorate %tex2D_src1 Binding 1
+ OpDecorate %samp DescriptorSet 0
+ OpDecorate %samp Binding 3
+ OpDecorate %tex2D_src2 DescriptorSet 0
+ OpDecorate %tex2D_src2 Binding 2
+ OpDecorate %tex2D_src1 BlockMatchTextureQCOM
+ OpDecorate %samp BlockMatchSamplerQCOM
+ OpDecorate %tex2D_src2 BlockMatchTextureQCOM
+ OpDecorate %samp BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %v_texcoord = OpVariable %_ptr_Input_v4float Input
+ %uint_0 = OpConstant %uint 0
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+ %uint_1 = OpConstant %uint 1
+ %uint_2 = OpConstant %uint 2
+ %uint_3 = OpConstant %uint 3
+ %uint_4 = OpConstant %uint 4
+ %39 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %fragColor = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %tex2D_src1 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %samp = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %tex2D_src2 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %tgt_coords = OpVariable %_ptr_Function_v2uint Function
+ %ref_coords = OpVariable %_ptr_Function_v2uint Function
+ %blockSize = OpVariable %_ptr_Function_v2uint Function
+ %16 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_0
+ %17 = OpLoad %float %16
+ %18 = OpConvertFToU %uint %17
+ %20 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %20 %18
+ %22 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_1
+ %23 = OpLoad %float %22
+ %24 = OpConvertFToU %uint %23
+ %25 = OpAccessChain %_ptr_Function_uint %tgt_coords %uint_0
+ OpStore %25 %24
+ %28 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_2
+ %29 = OpLoad %float %28
+ %30 = OpConvertFToU %uint %29
+ %31 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_0
+ OpStore %31 %30
+ %33 = OpAccessChain %_ptr_Input_float %v_texcoord %uint_3
+ %34 = OpLoad %float %33
+ %35 = OpConvertFToU %uint %34
+ %36 = OpAccessChain %_ptr_Function_uint %ref_coords %uint_1
+ OpStore %36 %35
+ OpStore %blockSize %39
+ %45 = OpLoad %42 %tex2D_src1
+ %49 = OpLoad %46 %samp
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %tgt_coords
+ %54 = OpLoad %42 %tex2D_src2
+ %55 = OpLoad %46 %samp
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %ref_coords
+ %58 = OpLoad %v2uint %blockSize
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %fragColor %59
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(str.c_str());
+ ASSERT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("2nd operand of Decorate"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("requires one of these extensions"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_QCOM_image_processing"));
+}
+
using ValidateAMDShaderBallotCapabilities = spvtest::ValidateBase<std::string>;
// Returns a vector of strings for the prefix of a SPIR-V assembly shader
diff --git a/third_party/SPIRV-Tools/test/val/val_id_test.cpp b/third_party/SPIRV-Tools/test/val/val_id_test.cpp
index 3666f38b0..cc2973696 100644
--- a/third_party/SPIRV-Tools/test/val/val_id_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_id_test.cpp
@@ -1056,7 +1056,7 @@ TEST_P(ValidateIdWithMessage, OpTypeArrayLengthNull) {
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr(make_message("OpTypeArray Length <id> '2[%2]' default "
- "value must be at least 1.")));
+ "value must be at least 1: found 0")));
}
TEST_P(ValidateIdWithMessage, OpTypeArrayLengthSpecConst) {
@@ -2317,7 +2317,7 @@ OpFunctionEnd
"be used with non-externally visible shader Storage Classes: "
"Workgroup, CrossWorkgroup, Private, Function, Input, Output, "
"RayPayloadKHR, IncomingRayPayloadKHR, HitAttributeKHR, "
- "CallableDataKHR, or IncomingCallableDataKHR")));
+ "CallableDataKHR, IncomingCallableDataKHR, or UniformConstant")));
}
TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPrivateGood) {
@@ -2339,6 +2339,25 @@ OpFunctionEnd
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_P(ValidateIdWithMessage, OpVariableContainsBoolUniformConstantGood) {
+ std::string spirv = kGLSL450MemoryModel + R"(
+%bool = OpTypeBool
+%int = OpTypeInt 32 0
+%block = OpTypeStruct %bool %int
+%_ptr_UniformConstant_block = OpTypePointer UniformConstant %block
+%var = OpVariable %_ptr_UniformConstant_block UniformConstant
+%void = OpTypeVoid
+%fnty = OpTypeFunction %void
+%main = OpFunction %void None %fnty
+%entry = OpLabel
+%load = OpLoad %block %var
+OpReturn
+OpFunctionEnd
+)";
+ CompileSuccessfully(spirv.c_str());
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
TEST_P(ValidateIdWithMessage, OpVariableContainsBoolPointerGood) {
std::string spirv = kGLSL450MemoryModel + R"(
%bool = OpTypeBool
@@ -4206,7 +4225,7 @@ OpReturn
OpFunctionEnd
)";
const std::string expected_err = "Index is out of bounds: " + instr +
- " can not find index 3 into the structure "
+ " cannot find index 3 into the structure "
"<id> '25[%_struct_25]'. This structure "
"has 3 members. Largest valid index is 2.";
CompileSuccessfully(spirv);
diff --git a/third_party/SPIRV-Tools/test/val/val_image_test.cpp b/third_party/SPIRV-Tools/test/val/val_image_test.cpp
index aa335c869..77b042f04 100644
--- a/third_party/SPIRV-Tools/test/val/val_image_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_image_test.cpp
@@ -786,6 +786,21 @@ TEST_F(ValidateImage, TypeImageWrongArrayForSubpassDataVulkan) {
HasSubstr("Dim SubpassData requires Arrayed to be 0"));
}
+TEST_F(ValidateImage, TypeImageDimRectVulkan) {
+ const std::string code = GetShaderHeader("OpCapability InputAttachment\n") +
+ R"(
+%img_type = OpTypeImage %f32 Rect 0 1 0 2 Unknown
+)" + TrivialMain();
+
+ CompileSuccessfully(code.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_CAPABILITY,
+ ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ // Can't actually hit VUID-StandaloneSpirv-OpTypeImage-09638
+ EXPECT_THAT(
+ getDiagnosticString(),
+ AnyVUID("TypeImage requires one of these capabilities: SampledRect"));
+}
+
TEST_F(ValidateImage, TypeImageWrongSampledTypeForTileImageDataEXT) {
const std::string code = GetShaderHeader(
"OpCapability TileImageColorReadAccessEXT\n"
@@ -2177,8 +2192,6 @@ TEST_F(ValidateImage, SampleImplicitLodVulkanMoreThanOneOffset) {
CompileSuccessfully(
GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_VULKAN_1_0).c_str());
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- AnyVUID("VUID-StandaloneSpirv-Offset-04662"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
@@ -5854,10 +5867,12 @@ TEST_F(ValidateImage, SignExtendV13Bad) {
%res1 = OpImageRead %u32vec4 %img %u32vec2_01 SignExtend
)";
- EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
- SPV_ENV_UNIVERSAL_1_3),
- SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION),
- HasSubstr("Invalid image operand 'SignExtend'"));
+ CompileSuccessfully(
+ GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
+ ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("SignExtend(4096) requires SPIR-V version 1.4 or later"));
}
TEST_F(ValidateImage, ZeroExtendV13Bad) {
@@ -5866,10 +5881,12 @@ TEST_F(ValidateImage, ZeroExtendV13Bad) {
%res1 = OpImageRead %u32vec4 %img %u32vec2_01 ZeroExtend
)";
- EXPECT_THAT(CompileFailure(GenerateShaderCode(body, "", "Fragment", "",
- SPV_ENV_UNIVERSAL_1_3),
- SPV_ENV_UNIVERSAL_1_3, SPV_ERROR_WRONG_VERSION),
- HasSubstr("Invalid image operand 'ZeroExtend'"));
+ CompileSuccessfully(
+ GenerateShaderCode(body, "", "Fragment", "", SPV_ENV_UNIVERSAL_1_3));
+ ASSERT_EQ(SPV_ERROR_WRONG_VERSION, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("ZeroExtend(8192) requires SPIR-V version 1.4 or later"));
}
TEST_F(ValidateImage, SignExtendScalarUIntTexelV14Good) {
@@ -6675,6 +6692,3961 @@ TEST_F(ValidateImage, NVBindlessInvalidAddressingMode) {
HasSubstr("OpSamplerImageAddressingModeNV bitwidth should be 64 or 32"));
}
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationA) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationB) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationC) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADNoDecorationD) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationA) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationB) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationC) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDNoDecorationD) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationA) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureSampleWeightedQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 Location 0
+ OpDecorate %7 DescriptorSet 0
+ OpDecorate %7 Binding 0
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
+ %4 = OpVariable %_ptr_UniformConstant_13 UniformConstant
+ %15 = OpTypeSampler
+%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
+ %5 = OpVariable %_ptr_UniformConstant_15 UniformConstant
+ %17 = OpTypeSampledImage %13
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %6 = OpVariable %_ptr_Input_v4float Input
+ %v2float = OpTypeVector %float 2
+ %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %22 = OpTypeSampledImage %20
+%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
+ %2 = OpFunction %void None %9
+ %24 = OpLabel
+ %25 = OpLoad %13 %4
+ %26 = OpLoad %15 %5
+ %27 = OpSampledImage %17 %25 %26
+ %28 = OpLoad %v4float %6
+ %29 = OpVectorShuffle %v2float %28 %28 0 1
+ %30 = OpLoad %20 %7
+ %31 = OpLoad %15 %5
+ %32 = OpSampledImage %22 %30 %31
+ %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration WeightTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedNoDecorationB) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureSampleWeightedQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+ %14 = OpTypeSampler
+%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
+ %16 = OpTypeSampledImage %12
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %4 = OpVariable %_ptr_Input_v4float Input
+ %v2float = OpTypeVector %float 2
+ %19 = OpTypeImage %float 2D 0 1 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %21 = OpTypeSampledImage %19
+%_ptr_UniformConstant_16 = OpTypePointer UniformConstant %16
+ %5 = OpVariable %_ptr_UniformConstant_16 UniformConstant
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %6 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpLoad %16 %5
+ %26 = OpLoad %v4float %4
+ %27 = OpVectorShuffle %v2float %26 %26 0 1
+ %28 = OpLoad %21 %6
+ %29 = OpImageSampleWeightedQCOM %v4float %25 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration WeightTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchWindowSADInvalidUseA) {
+ std::string text = R"(
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 11
+; Bound: 79
+; Schema: 0
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseB) {
+ std::string text = R"(
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 11
+; Bound: 79
+; Schema: 0
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseC) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSADInvalidUseD) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseA) {
+ std::string text = R"(
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 11
+; Bound: 79
+; Schema: 0
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseB) {
+ std::string text = R"(
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 11
+; Bound: 79
+; Schema: 0
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseC) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingBlockMatchSSDInvalidUseD) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseA) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureSampleWeightedQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %6 WeightTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %12 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_12 = OpTypePointer UniformConstant %12
+ %14 = OpTypeSampledImage %12
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %4 = OpVariable %_ptr_Input_v4float Input
+ %v2float = OpTypeVector %float 2
+ %17 = OpTypeImage %float 2D 0 1 0 1 Unknown
+%_ptr_UniformConstant_17 = OpTypePointer UniformConstant %17
+ %19 = OpTypeSampledImage %17
+%_ptr_UniformConstant_14 = OpTypePointer UniformConstant %14
+ %5 = OpVariable %_ptr_UniformConstant_14 UniformConstant
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %v3float = OpTypeVector %float 3
+ %2 = OpFunction %void None %8
+ %23 = OpLabel
+ %24 = OpLoad %v4float %4
+ %25 = OpVectorShuffle %v2float %24 %24 0 1
+ %26 = OpLoad %14 %5
+ %27 = OpLoad %v4float %4
+ %28 = OpVectorShuffle %v2float %27 %27 0 1
+ %29 = OpLoad %19 %6
+ %30 = OpImageSampleWeightedQCOM %v4float %26 %28 %29
+ OpStore %3 %30
+ %31 = OpLoad %19 %6
+ %32 = OpLoad %v4float %4
+ %33 = OpVectorShuffle %v3float %32 %32 0 1 0
+ %34 = OpCompositeExtract %float %33 0
+ %35 = OpCompositeExtract %float %33 1
+ %36 = OpCompositeExtract %float %33 2
+ %37 = OpCompositeConstruct %v3float %34 %35 %36
+ %38 = OpImageSampleImplicitLod %v4float %31 %37
+ OpStore %3 %38
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessingSampleWeightedInvalidUseB) {
+ std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureSampleWeightedQCOM
+ OpExtension "SPV_QCOM_image_processing"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6 %7
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 1
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 3
+ OpDecorate %4 Location 0
+ OpDecorate %7 DescriptorSet 0
+ OpDecorate %7 Binding 0
+ OpDecorate %7 WeightTextureQCOM
+ %void = OpTypeVoid
+ %9 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %13 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_13 = OpTypePointer UniformConstant %13
+ %5 = OpVariable %_ptr_UniformConstant_13 UniformConstant
+ %15 = OpTypeSampler
+%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
+ %6 = OpVariable %_ptr_UniformConstant_15 UniformConstant
+ %17 = OpTypeSampledImage %13
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %4 = OpVariable %_ptr_Input_v4float Input
+ %v2float = OpTypeVector %float 2
+ %20 = OpTypeImage %float 2D 0 1 0 1 Unknown
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %7 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %22 = OpTypeSampledImage %20
+ %v3float = OpTypeVector %float 3
+ %2 = OpFunction %void None %9
+ %24 = OpLabel
+ %25 = OpLoad %13 %5
+ %26 = OpLoad %15 %6
+ %27 = OpSampledImage %17 %25 %26
+ %28 = OpLoad %v4float %4
+ %29 = OpVectorShuffle %v2float %28 %28 0 1
+ %30 = OpLoad %20 %7
+ %31 = OpLoad %15 %6
+ %32 = OpSampledImage %22 %30 %31
+ %33 = OpImageSampleWeightedQCOM %v4float %27 %29 %32
+ OpStore %3 %33
+ %34 = OpLoad %20 %7
+ %35 = OpLoad %15 %6
+ %36 = OpSampledImage %22 %34 %35
+ %37 = OpLoad %v4float %4
+ %38 = OpVectorShuffle %v3float %37 %37 0 1 0
+ %39 = OpCompositeExtract %float %38 0
+ %40 = OpCompositeExtract %float %38 1
+ %41 = OpCompositeExtract %float %38 2
+ %42 = OpCompositeConstruct %v3float %39 %40 %41
+ %43 = OpImageSampleImplicitLod %v4float %36 %42
+ OpStore %3 %43
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorTargetNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADNoDecorRefNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchWindowSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorTargetNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDNoDecorRefNIS) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %4 BlockMatchSamplerQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchWindowSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchSamplerQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSADQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSADQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 4
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 5
+ %void = OpTypeVoid
+ %7 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %19 = OpTypeSampledImage %18
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %5 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %7
+ %22 = OpLabel
+ %23 = OpVariable %_ptr_Function_v2uint Function
+ %24 = OpLoad %19 %4
+ %25 = OpLoad %v2uint %23
+ %26 = OpLoad %19 %5
+ %27 = OpLoad %v2uint %23
+ %28 = OpLoad %v2uint %23
+ %29 = OpImageBlockMatchGatherSSDQCOM %v4float %24 %25 %26 %27 %28
+ OpStore %3 %29
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorTargetNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDNoDecorRefNIT) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 DescriptorSet 0
+ OpDecorate %4 Binding 1
+ OpDecorate %4 BlockMatchTextureQCOM
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 3
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 2
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+%v4float = OpTypeVector %float 4
+%_ptr_Input_float = OpTypePointer Input %float
+%_ptr_Function_uint = OpTypePointer Function %uint
+%uint_4 = OpConstant %uint 4
+ %17 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %3 = OpVariable %_ptr_Output_v4float Output
+ %19 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_19 = OpTypePointer UniformConstant %19
+ %4 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %21 = OpTypeSampler
+%_ptr_UniformConstant_21 = OpTypePointer UniformConstant %21
+ %5 = OpVariable %_ptr_UniformConstant_21 UniformConstant
+ %23 = OpTypeSampledImage %19
+ %6 = OpVariable %_ptr_UniformConstant_19 UniformConstant
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ %26 = OpLoad %19 %4
+ %27 = OpLoad %21 %5
+ %28 = OpSampledImage %23 %26 %27
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %19 %6
+ %31 = OpLoad %21 %5
+ %32 = OpSampledImage %23 %30 %31
+ %33 = OpImageBlockMatchGatherSSDQCOM %v4float %28 %29 %32 %29 %29
+ OpStore %3 %33
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Missing decoration BlockMatchTextureQCOM"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSADInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %103 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSADInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %103 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %5 BlockMatchSamplerQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchSamplerQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchWindowSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchWindowSSDInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %103 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchWindowSSDInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %103 BlockMatchSamplerQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchWindowSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSADQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSADInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSADInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSADQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %5
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %2 "main" %3 %4 %5 %6
+ OpExecutionMode %2 OriginUpperLeft
+ OpDecorate %3 Location 0
+ OpDecorate %4 Location 0
+ OpDecorate %5 DescriptorSet 0
+ OpDecorate %5 Binding 4
+ OpDecorate %6 DescriptorSet 0
+ OpDecorate %6 Binding 5
+ OpDecorate %5 BlockMatchTextureQCOM
+ OpDecorate %6 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %8 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %3 = OpVariable %_ptr_Input_v4float Input
+ %uint_4 = OpConstant %uint 4
+ %16 = OpConstantComposite %v2uint %uint_4 %uint_4
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %4 = OpVariable %_ptr_Output_v4float Output
+ %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+ %20 = OpTypeSampledImage %18
+%_ptr_UniformConstant_20 = OpTypePointer UniformConstant %20
+ %5 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %6 = OpVariable %_ptr_UniformConstant_20 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %23 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %2 = OpFunction %void None %8
+ %24 = OpLabel
+ %25 = OpVariable %_ptr_Function_v2uint Function
+ OpStore %25 %16
+ %26 = OpLoad %20 %5
+ %27 = OpLoad %v2uint %25
+ %28 = OpLoad %20 %6
+ %29 = OpLoad %v2uint %25
+ %30 = OpLoad %v2uint %25
+ %31 = OpImageBlockMatchGatherSSDQCOM %v4float %26 %27 %28 %29 %30
+ OpStore %4 %31
+ %32 = OpLoad %20 %6
+ %33 = OpLoad %v4float %3
+ %34 = OpVectorShuffle %v2float %33 %33 0 2
+ %35 = OpImageSampleImplicitLod %v4float %32 %34
+ OpStore %4 %35
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage,
+ QCOMImageProcessing2BlockMatchGatherSSDInvalidUseTargetNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %102
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, QCOMImageProcessing2BlockMatchGatherSSDInvalidUseRefNI) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpCapability TextureBlockMatchQCOM
+ OpCapability TextureBlockMatch2QCOM
+ OpExtension "SPV_QCOM_image_processing"
+ OpExtension "SPV_QCOM_image_processing2"
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %100 %101 %102 %103 %104
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %100 Location 0
+ OpDecorate %101 Location 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+ OpDecorate %102 BlockMatchTextureQCOM
+ OpDecorate %104 BlockMatchTextureQCOM
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %uint = OpTypeInt 32 0
+ %v2uint = OpTypeVector %uint 2
+%_ptr_Function_v2uint = OpTypePointer Function %v2uint
+ %float = OpTypeFloat 32
+ %v4float = OpTypeVector %float 4
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+ %100 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+ %101 = OpVariable %_ptr_Output_v4float Output
+ %42 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_42 = OpTypePointer UniformConstant %42
+ %102 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %46 = OpTypeSampler
+%_ptr_UniformConstant_46 = OpTypePointer UniformConstant %46
+ %103 = OpVariable %_ptr_UniformConstant_46 UniformConstant
+ %50 = OpTypeSampledImage %42
+ %104 = OpVariable %_ptr_UniformConstant_42 UniformConstant
+ %v2float = OpTypeVector %float 2
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ %15 = OpVariable %_ptr_Function_v2uint Function
+ %45 = OpLoad %42 %102
+ %49 = OpLoad %46 %103
+ %51 = OpSampledImage %50 %45 %49
+ %52 = OpLoad %v2uint %15
+ %54 = OpLoad %42 %104
+ %55 = OpLoad %46 %103
+ %56 = OpSampledImage %50 %54 %55
+ %57 = OpLoad %v2uint %15
+ %58 = OpLoad %v2uint %15
+ %59 = OpImageBlockMatchGatherSSDQCOM %v4float %51 %52 %56 %57 %58
+ OpStore %101 %59
+ %69 = OpLoad %42 %104
+ %70 = OpLoad %46 %103
+ %71 = OpSampledImage %50 %69 %70
+ %73 = OpLoad %v4float %100
+ %74 = OpVectorShuffle %v2float %73 %73 0 0
+ %75 = OpImageSampleImplicitLod %v4float %71 %74
+ OpStore %101 %75
+ OpReturn
+ OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Illegal use of QCOM image processing decorated texture"));
+}
+
+TEST_F(ValidateImage, ImageMSArray_ArrayedSampledTypeRequiresCapability) {
+ const std::string code = R"(
+ OpCapability Shader
+ OpCapability StorageImageMultisample
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v2uint = OpTypeVector %u32 2
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 1 1 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v2uint %uint_1 %uint_2
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10 Sample %uint_2
+ OpReturn
+ OpFunctionEnd
+)";
+
+ const spv_target_env env = SPV_ENV_VULKAN_1_0;
+ CompileSuccessfully(code, env);
+ ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(env));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Capability ImageMSArray is required to access storage image"));
+}
+
+TEST_F(ValidateImage, ImageMSArray_SampledTypeDoesNotRequireCapability) {
+ const std::string code = R"(
+ OpCapability Shader
+ OpCapability StorageImageMultisample
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v2uint = OpTypeVector %u32 2
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 0 1 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v2uint %uint_1 %uint_2
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10 Sample %uint_2
+ OpReturn
+ OpFunctionEnd
+)";
+
+ const spv_target_env env = SPV_ENV_VULKAN_1_0;
+ CompileSuccessfully(code, env);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
+ EXPECT_THAT(getDiagnosticString(), Eq(""));
+}
+
+TEST_F(ValidateImage, ImageMSArray_ArrayedTypeDoesNotRequireCapability) {
+ const std::string code = R"(
+ OpCapability Shader
+ OpCapability StorageImageReadWithoutFormat
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpDecorate %var_image DescriptorSet 0
+ OpDecorate %var_image Binding 1
+ %void = OpTypeVoid
+ %func = OpTypeFunction %void
+ %f32 = OpTypeFloat 32
+ %u32 = OpTypeInt 32 0
+ %uint_3 = OpConstant %u32 3
+ %uint_2 = OpConstant %u32 2
+ %uint_1 = OpConstant %u32 1
+ %v3uint = OpTypeVector %u32 3
+ %v4float = OpTypeVector %f32 4
+ %image = OpTypeImage %f32 2D 2 1 0 2 Unknown
+%ptr_image = OpTypePointer UniformConstant %image
+ %10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
+%var_image = OpVariable %ptr_image UniformConstant
+ %main = OpFunction %void None %func
+ %main_lab = OpLabel
+ %18 = OpLoad %image %var_image
+ %19 = OpImageRead %v4float %18 %10
+ OpReturn
+ OpFunctionEnd
+)";
+
+ const spv_target_env env = SPV_ENV_VULKAN_1_0;
+ CompileSuccessfully(code, env);
+ ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(env));
+ EXPECT_THAT(getDiagnosticString(), Eq(""));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_interfaces_test.cpp b/third_party/SPIRV-Tools/test/val/val_interfaces_test.cpp
index 175652872..4f62be799 100644
--- a/third_party/SPIRV-Tools/test/val/val_interfaces_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_interfaces_test.cpp
@@ -419,9 +419,10 @@ OpFunctionEnd
)";
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable has conflicting location decorations"));
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("decorated with Location multiple times is not allowed"));
}
TEST_F(ValidateInterfacesTest, VulkanLocationsVariableAndMemberAssigned) {
@@ -505,9 +506,10 @@ OpFunctionEnd
)";
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Member index 1 has conflicting location assignments"));
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("decorated with Location multiple times is not allowed"));
}
TEST_F(ValidateInterfacesTest, VulkanLocationsMissingAssignmentStructMember) {
@@ -584,6 +586,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 0"));
}
@@ -611,6 +615,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Entry-point has conflicting output location assignment "
@@ -699,6 +705,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1"));
}
@@ -732,6 +740,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1"));
}
@@ -762,6 +772,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1"));
}
@@ -792,6 +804,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 2"));
}
@@ -822,6 +836,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 3"));
}
@@ -854,6 +870,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1"));
}
@@ -886,6 +904,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 5"));
}
@@ -918,6 +938,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 7"));
}
@@ -950,6 +972,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1"));
}
@@ -982,6 +1006,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 3"));
}
@@ -1016,6 +1042,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 15"));
}
@@ -1075,6 +1103,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08721"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting input location assignment "
"at location 1, component 1"));
}
@@ -1129,9 +1159,10 @@ OpFunctionEnd
)";
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
- EXPECT_THAT(getDiagnosticString(),
- HasSubstr("Variable has conflicting component decorations"));
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("decorated with Component multiple times is not allowed"));
}
TEST_F(ValidateInterfacesTest,
@@ -1158,10 +1189,10 @@ OpFunctionEnd
)";
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
- EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(
getDiagnosticString(),
- HasSubstr("Member index 0 has conflicting component assignments"));
+ HasSubstr("decorated with Component multiple times is not allowed"));
}
TEST_F(ValidateInterfacesTest, VulkanLocationsVariableConflictOutputIndex1) {
@@ -1189,6 +1220,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("Entry-point has conflicting output location assignment "
@@ -1359,6 +1392,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-08722"));
+ EXPECT_THAT(getDiagnosticString(),
HasSubstr("Entry-point has conflicting output location "
"assignment at location 1, component 1"));
}
@@ -1538,6 +1573,58 @@ OpFunctionEnd
"Interface struct has no Block decoration but has BuiltIn members."));
}
+TEST_F(ValidateInterfacesTest, InvalidLocationTypePointer) {
+ const std::string text = R"(
+ OpCapability Shader
+ OpMemoryModel Logical Simple
+ OpEntryPoint Vertex %1 "Aiqn0" %2 %3
+ OpDecorate %2 Location 0
+ %void = OpTypeVoid
+ %5 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+%_ptr_Private_void = OpTypePointer Private %void
+ %uint = OpTypeInt 32 0
+%uint_4278132784 = OpConstant %uint 4278132784
+%_arr__ptr_Private_void_uint_4278132784 = OpTypeArray %_ptr_Private_void %uint_4278132784
+%_ptr_Output__arr__ptr_Private_void_uint_4278132784 = OpTypePointer Output %_arr__ptr_Private_void_uint_4278132784
+ %2 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output
+%_ptr_Output__ptr_Private_void = OpTypePointer Output %_ptr_Private_void
+ %3 = OpVariable %_ptr_Output__arr__ptr_Private_void_uint_4278132784 Output
+ %1 = OpFunction %void None %5
+ %15 = OpLabel
+ OpReturn
+ OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_VULKAN_1_1);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Invalid type to assign a location"));
+}
+
+TEST_F(ValidateInterfacesTest, ValidLocationTypePhysicalStorageBufferPointer) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability PhysicalStorageBufferAddresses
+OpMemoryModel PhysicalStorageBuffer64 GLSL450
+OpEntryPoint Vertex %main "main" %var
+OpDecorate %var Location 0
+OpDecorate %var RestrictPointer
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%ptr = OpTypePointer PhysicalStorageBuffer %int
+%ptr2 = OpTypePointer Input %ptr
+%var = OpVariable %ptr2 Input
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+ CompileSuccessfully(text, SPV_ENV_VULKAN_1_3);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
index d57531895..74a17e984 100644
--- a/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_memory_test.cpp
@@ -23,12 +23,14 @@
#include "test/val/val_fixtures.h"
// For pretty-printing tuples with spv_target_env.
-std::ostream& operator<<(std::ostream& stream, spv_target_env target)
-{
+std::ostream& operator<<(std::ostream& stream, spv_target_env target) {
switch (target) {
- case SPV_ENV_UNIVERSAL_1_3: return stream << "SPV_ENV_UNIVERSAL_1_3";
- case SPV_ENV_UNIVERSAL_1_4: return stream << "SPV_ENV_UNIVERSAL_1_4";
- default: return stream << (unsigned)target;
+ case SPV_ENV_UNIVERSAL_1_3:
+ return stream << "SPV_ENV_UNIVERSAL_1_3";
+ case SPV_ENV_UNIVERSAL_1_4:
+ return stream << "SPV_ENV_UNIVERSAL_1_4";
+ default:
+ return stream << (unsigned)target;
}
}
@@ -2346,6 +2348,186 @@ OpFunctionEnd)";
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
}
+TEST_F(ValidateMemory, CoopMatKHRLoadStoreSuccess) {
+ std::string spirv =
+ GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
+ "MakePointerVisibleKHR|NonPrivatePointerKHR");
+
+ CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+}
+
+TEST_F(ValidateMemory, CoopMatKHRStoreMemoryAccessFail) {
+ std::string spirv =
+ GenCoopMatLoadStoreShader("MakePointerVisibleKHR|NonPrivatePointerKHR",
+ "MakePointerVisibleKHR|NonPrivatePointerKHR");
+
+ CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("MakePointerVisibleKHR cannot be used with OpStore"));
+}
+
+TEST_F(ValidateMemory, CoopMatKHRLoadMemoryAccessFail) {
+ std::string spirv =
+ GenCoopMatLoadStoreShader("MakePointerAvailableKHR|NonPrivatePointerKHR",
+ "MakePointerAvailableKHR|NonPrivatePointerKHR");
+
+ CompileSuccessfully(spirv.c_str(), SPV_ENV_VULKAN_1_1);
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_1));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("MakePointerAvailableKHR cannot be used with OpLoad"));
+}
+
+TEST_F(ValidateMemory, CoopMatKHRInvalidStorageClassFail) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%f16 = OpTypeFloat 16
+%u32 = OpTypeInt 32 0
+
+%u32_8 = OpConstant %u32 8
+%use_A = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+
+%str = OpTypeStruct %f16mat
+%str_ptr = OpTypePointer Workgroup %str
+%sh = OpVariable %str_ptr Workgroup
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Cooperative matrix types (or types containing them) can only be "
+ "allocated in Function or Private storage classes or as function "
+ "parameters"));
+}
+
+TEST_F(ValidateMemory, CoopMatMatrixKHRLengthResultTypeBad) {
+ const std::string body = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%f16 = OpTypeFloat 16
+%u32 = OpTypeInt 32 0
+%i32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%use_A = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%1 = OpCooperativeMatrixLengthKHR %i32 %f16mat
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The Result Type of OpCooperativeMatrixLengthKHR <id> "
+ "'12[%12]' must be OpTypeInt with width 32 and signedness 0"));
+}
+
+TEST_F(ValidateMemory, CoopMatMatrixKHRLengthOperandTypeBad) {
+ const std::string body =
+ R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%f16 = OpTypeFloat 16
+%u32 = OpTypeInt 32 0
+%i32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%use_A = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%1 = OpCooperativeMatrixLengthKHR %u32 %u32
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The type in OpCooperativeMatrixLengthKHR <id> '5[%uint]' "
+ "must be OpTypeCooperativeMatrixKHR"));
+}
+
+TEST_F(ValidateMemory, CoopMatMatrixKHRLengthGood) {
+ const std::string body =
+ R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability CooperativeMatrixKHR
+OpExtension "SPV_KHR_cooperative_matrix"
+OpExtension "SPV_KHR_vulkan_memory_model"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%f16 = OpTypeFloat 16
+%u32 = OpTypeInt 32 0
+%i32 = OpTypeInt 32 1
+
+%u32_8 = OpConstant %u32 8
+%use_A = OpConstant %u32 0
+%subgroup = OpConstant %u32 3
+
+%f16mat = OpTypeCooperativeMatrixKHR %f16 %subgroup %u32_8 %u32_8 %use_A
+
+%main = OpFunction %void None %func
+%main_entry = OpLabel
+
+%1 = OpCooperativeMatrixLengthKHR %u32 %f16mat
+
+OpReturn
+OpFunctionEnd)";
+
+ CompileSuccessfully(body.c_str());
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
TEST_F(ValidateMemory, VulkanRTAOutsideOfStructBad) {
std::string spirv = R"(
OpCapability Shader
@@ -3765,9 +3947,8 @@ OpFunctionEnd
HasSubstr("In the Vulkan environment, cannot store to Uniform Blocks"));
}
-using ValidateSizedVariable =
- spvtest::ValidateBase<std::tuple<std::string, std::string,
- std::string, spv_target_env>>;
+using ValidateSizedVariable = spvtest::ValidateBase<
+ std::tuple<std::string, std::string, std::string, spv_target_env>>;
CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) {
CodeGenerator generator;
@@ -3777,7 +3958,8 @@ CodeGenerator GetSizedVariableCodeGenerator(bool is_8bit, bool buffer_block) {
"\"SPV_KHR_8bit_storage\"\n";
generator.memory_model_ = "OpMemoryModel Logical GLSL450\n";
if (is_8bit) {
- generator.before_types_ = "OpMemberDecorate %char_buffer_block 0 Offset 0\n";
+ generator.before_types_ =
+ "OpMemberDecorate %char_buffer_block 0 Offset 0\n";
if (buffer_block)
generator.before_types_ += "OpDecorate %char_buffer_block BufferBlock\n";
@@ -4933,6 +5115,60 @@ TEST_F(ValidateMemory, VulkanPtrAccessChainWorkgroupNoArrayStrideSuccess) {
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
}
+TEST_F(ValidateMemory, AccessChainNegativeStructIndex32) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%_struct_4 = OpTypeStruct %int %int %int
+%_ptr_Function__struct_4 = OpTypePointer Function %_struct_4
+%_ptr_Function_int = OpTypePointer Function %int
+%int_n224 = OpConstant %int -224
+%fn = OpFunction %void Inline %void_fn
+%entry = OpLabel
+%var = OpVariable %_ptr_Function__struct_4 Function
+%gep = OpInBoundsAccessChain %_ptr_Function_int %var %int_n224
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("Index is out of bounds"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("cannot find index -224"));
+}
+
+TEST_F(ValidateMemory, AccessChainNegativeStructIndex64) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Linkage
+OpCapability Int64
+OpMemoryModel Logical GLSL450
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%long = OpTypeInt 64 1
+%_struct_4 = OpTypeStruct %int %int %int
+%_ptr_Function__struct_4 = OpTypePointer Function %_struct_4
+%_ptr_Function_int = OpTypePointer Function %int
+%long_n224 = OpConstant %long -224
+%fn = OpFunction %void Inline %void_fn
+%entry = OpLabel
+%var = OpVariable %_ptr_Function__struct_4 Function
+%gep = OpInBoundsAccessChain %_ptr_Function_int %var %long_n224
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("Index is out of bounds"));
+ EXPECT_THAT(getDiagnosticString(), HasSubstr("cannot find index -224"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_modes_test.cpp b/third_party/SPIRV-Tools/test/val/val_modes_test.cpp
index 8dc0fbc5a..83a050377 100644
--- a/third_party/SPIRV-Tools/test/val/val_modes_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_modes_test.cpp
@@ -1027,6 +1027,162 @@ OpExecutionModeId %main LocalSizeId %int_1 %int_1 %int_1
"constant instructions."));
}
+using AllowMultipleExecutionModes = spvtest::ValidateBase<std::string>;
+
+TEST_P(AllowMultipleExecutionModes, DifferentOperand) {
+ const std::string mode = GetParam();
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability DenormPreserve
+OpCapability DenormFlushToZero
+OpCapability SignedZeroInfNanPreserve
+OpCapability RoundingModeRTE
+OpCapability RoundingModeRTZ
+OpExtension "SPV_KHR_float_controls"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main )" + mode +
+ R"( 16
+OpExecutionMode %main )" + mode +
+ R"( 32
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
+}
+
+TEST_P(AllowMultipleExecutionModes, SameOperand) {
+ const std::string mode = GetParam();
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability DenormPreserve
+OpCapability DenormFlushToZero
+OpCapability SignedZeroInfNanPreserve
+OpCapability RoundingModeRTE
+OpCapability RoundingModeRTZ
+OpExtension "SPV_KHR_float_controls"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main )" + mode +
+ R"( 32
+OpExecutionMode %main )" + mode +
+ R"( 32
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("execution mode must not be specified multiple times "
+ "for the same entry point and operands"));
+}
+
+INSTANTIATE_TEST_SUITE_P(MultipleFloatControlsExecModes,
+ AllowMultipleExecutionModes,
+ Values("DenormPreserve", "DenormFlushToZero",
+ "SignedZeroInfNanPreserve", "RoundingModeRTE",
+ "RoundingModeRTZ"));
+
+using MultipleExecModes = spvtest::ValidateBase<std::string>;
+
+TEST_P(MultipleExecModes, DuplicateMode) {
+ const std::string mode = GetParam();
+ const std::string spirv = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint Fragment %main "main"
+OpExecutionMode %main OriginUpperLeft
+OpExecutionMode %main )" + mode +
+ R"(
+OpExecutionMode %main )" + mode +
+ R"(
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("execution mode must not be specified multiple times "
+ "per entry point"));
+}
+
+INSTANTIATE_TEST_SUITE_P(MultipleFragmentExecMode, MultipleExecModes,
+ Values("DepthReplacing", "DepthGreater", "DepthLess",
+ "DepthUnchanged"));
+
+TEST_F(ValidateMode, FloatControls2FPFastMathDefaultSameOperand) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %none
+OpExecutionModeId %main FPFastMathDefault %float %none
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 0
+%none = OpConstant %int 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("execution mode must not be specified multiple times "
+ "for the same entry point and operands"));
+}
+
+TEST_F(ValidateMode, FloatControls2FPFastMathDefaultDifferentOperand) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Float16
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %none
+OpExecutionModeId %main FPFastMathDefault %half %none
+%void = OpTypeVoid
+%float = OpTypeFloat 32
+%int = OpTypeInt 32 0
+%none = OpConstant %int 0
+%half = OpTypeFloat 16
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_2);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
+}
+
TEST_F(ValidateMode, FragmentShaderInterlockVertexBad) {
const std::string spirv = R"(
OpCapability Shader
@@ -1306,6 +1462,752 @@ OpFunctionEnd
EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_3));
}
+TEST_F(ValidateMode, MaximalReconvergenceRequiresExtension) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main MaximallyReconvergesKHR
+%void = OpTypeVoid
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_MISSING_EXTENSION, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("(6023) requires one of these extensions: "
+ "SPV_KHR_maximal_reconvergence "));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNotExecutionModeId) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionMode %main FPFastMathDefault %int_0 %int_0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("OpExecutionMode is only valid when the Mode operand "
+ "is an execution mode that takes no Extra Operands, or "
+ "takes Extra Operands that are not id operands"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNotAType) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %int_0 %int_0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "The Target Type operand must be a floating-point scalar type"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNotAFloatType) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %int %int_0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "The Target Type operand must be a floating-point scalar type"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNotAFloatScalarType) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float2 %int_0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%float = OpTypeFloat 32
+%float2 = OpTypeVector %float 2
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "The Target Type operand must be a floating-point scalar type"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultSpecConstant) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %int_0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpSpecConstant %int 0
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand must be a "
+ "non-specialization constant"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultInvalidMask) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 524288
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand is an invalid bitmask value"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultContainsFast) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 16
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand must not include Fast"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultAllowTransformMissingAllowReassoc) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 327680
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand must include AllowContract and "
+ "AllowReassoc when AllowTransform is specified"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultAllowTransformMissingAllowContract) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 393216
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand must include AllowContract and "
+ "AllowReassoc when AllowTransform is specified"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultAllowTransformMissingContractAndReassoc) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 262144
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("The Fast Math Default operand must include AllowContract and "
+ "AllowReassoc when AllowTransform is specified"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultSignedZeroInfNanPreserve) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpCapability SignedZeroInfNanPreserve
+OpExtension "SPV_KHR_float_controls2"
+OpExtension "SPV_KHR_float_controls"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionMode %main LocalSize 1 1 1
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main SignedZeroInfNanPreserve 32
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("FPFastMathDefault and SignedZeroInfNanPreserve execution "
+ "modes cannot be applied to the same entry point"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultConractionOff) {
+ const std::string spirv = R"(
+OpCapability Kernel
+OpCapability Addresses
+OpCapability FloatControls2
+OpCapability SignedZeroInfNanPreserve
+OpExtension "SPV_KHR_float_controls2"
+OpExtension "SPV_KHR_float_controls"
+OpMemoryModel Physical64 OpenCL
+OpEntryPoint Kernel %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main ContractionOff
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("FPFastMathDefault and ContractionOff execution modes "
+ "cannot be applied to the same entry point"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNoContractionNotInCallTree) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add NoContraction
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %zero %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNoContractionInCallTree) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add NoContraction
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %zero %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("NoContraction cannot be used by an entry point with "
+ "the FPFastMathDefault execution mode"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultNoContractionInCallTree2) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability Kernel
+OpCapability Addresses
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Physical64 OpenCL
+OpEntryPoint Kernel %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpDecorate %const NoContraction
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%const = OpSpecConstantOp %float FAdd %zero %zero
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %const %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("NoContraction cannot be used by an entry point with "
+ "the FPFastMathDefault execution mode"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultFastMathFastNotInCallTree) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode Fast
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %zero %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultFastMathFastInCallTree) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %add FPFastMathMode Fast
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %zero %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("FPFastMathMode Fast cannot be used by an entry point "
+ "with the FPFastMathDefault execution mode"));
+}
+
+TEST_F(ValidateMode, FPFastMathDefaultFastMathFastInCallTree2) {
+ const std::string spirv = R"(
+OpCapability Kernel
+OpCapability Addresses
+OpCapability FloatControls2
+OpExtension "SPV_KHR_float_controls2"
+OpMemoryModel Physical64 OpenCL
+OpEntryPoint Kernel %main "main"
+OpExecutionModeId %main FPFastMathDefault %float %constant
+OpDecorate %const FPFastMathMode Fast
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%constant = OpConstant %int 0
+%float = OpTypeFloat 32
+%zero = OpConstant %float 0
+%const = OpSpecConstantOp %float FAdd %zero %zero
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%call = OpFunctionCall %void %func
+OpReturn
+OpFunctionEnd
+%func = OpFunction %void None %void_fn
+%func_entry = OpLabel
+%add = OpFAdd %float %const %zero
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("FPFastMathMode Fast cannot be used by an entry point "
+ "with the FPFastMathDefault execution mode"));
+}
+
+TEST_F(ValidateMode, FragmentShaderRequireFullQuadsKHR) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability GroupNonUniform
+OpCapability GroupNonUniformVote
+OpCapability GroupNonUniformBallot
+OpCapability QuadControlKHR
+OpExtension "SPV_KHR_quad_control"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %4 "main"
+OpExecutionMode %4 OriginUpperLeft
+OpExecutionMode %4 RequireFullQuadsKHR
+OpDecorate %17 Location 0
+OpDecorate %31 BuiltIn HelperInvocation
+OpDecorate %40 Location 0
+OpDecorate %44 DescriptorSet 0
+OpDecorate %44 Binding 0
+%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%7 = OpTypeVector %6 4
+%8 = OpTypePointer Function %7
+%10 = OpTypeBool
+%11 = OpConstantTrue %10
+%12 = OpConstant %6 7
+%14 = OpTypeFloat 32
+%15 = OpTypeVector %14 4
+%16 = OpTypePointer Output %15
+%17 = OpVariable %16 Output
+%18 = OpConstant %14 1
+%19 = OpConstant %14 0
+%20 = OpConstantComposite %15 %18 %19 %19 %18
+%23 = OpConstant %6 4
+%27 = OpConstant %6 1
+%28 = OpTypePointer Output %14
+%30 = OpTypePointer Input %10
+%31 = OpVariable %30 Input
+%36 = OpConstant %6 2
+%38 = OpTypeVector %14 2
+%39 = OpTypePointer Input %38
+%40 = OpVariable %39 Input
+%41 = OpTypeImage %14 2D 0 0 0 1 Unknown
+%42 = OpTypeSampledImage %41
+%43 = OpTypePointer UniformConstant %42
+%44 = OpVariable %43 UniformConstant
+%4 = OpFunction %2 None %3
+%5 = OpLabel
+%9 = OpVariable %8 Function
+%13 = OpGroupNonUniformBallot %7 %12 %11
+OpStore %9 %13
+OpStore %17 %20
+%21 = OpLoad %7 %9
+%22 = OpGroupNonUniformBallotBitCount %6 %12 Reduce %21
+%24 = OpIEqual %10 %22 %23
+OpSelectionMerge %26 None
+OpBranchConditional %24 %25 %26
+%25 = OpLabel
+%29 = OpAccessChain %28 %17 %27
+OpStore %29 %18
+OpBranch %26
+%26 = OpLabel
+%32 = OpLoad %10 %31
+%33 = OpGroupNonUniformAny %10 %12 %32
+OpSelectionMerge %35 None
+OpBranchConditional %33 %34 %35
+%34 = OpLabel
+%37 = OpAccessChain %28 %17 %36
+OpStore %37 %18
+OpBranch %35
+%35 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_THAT(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Execution mode can only be used with the Fragment execution model"));
+}
+
+TEST_F(ValidateMode, FragmentShaderQuadDerivativesKHR) {
+ const std::string spirv = R"(
+OpCapability Shader
+OpCapability GroupNonUniform
+OpCapability GroupNonUniformVote
+OpCapability QuadControlKHR
+OpExtension "SPV_KHR_quad_control"
+%1 = OpExtInstImport "GLSL.std.450"
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %4 "main"
+OpExecutionMode %4 OriginUpperLeft
+OpExecutionMode %4 QuadDerivativesKHR
+OpDecorate %12 BuiltIn FragCoord
+OpDecorate %41 Location 0
+OpDecorate %45 DescriptorSet 0
+OpDecorate %45 Binding 0
+OpDecorate %49 Location 0
+%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+%6 = OpTypeBool
+%7 = OpTypePointer Function %6
+%9 = OpTypeFloat 32
+%10 = OpTypeVector %9 4
+%11 = OpTypePointer Input %10
+%12 = OpVariable %11 Input
+%13 = OpTypeInt 32 0
+%14 = OpConstant %13 1
+%15 = OpTypePointer Input %9
+%18 = OpConstant %9 8.5
+%21 = OpConstant %9 0.100000001
+%25 = OpConstant %13 0
+%28 = OpConstant %9 3.5
+%30 = OpConstant %9 6
+%36 = OpConstant %13 7
+%40 = OpTypePointer Output %10
+%41 = OpVariable %40 Output
+%42 = OpTypeImage %9 2D 0 0 0 1 Unknown
+%43 = OpTypeSampledImage %42
+%44 = OpTypePointer UniformConstant %43
+%45 = OpVariable %44 UniformConstant
+%47 = OpTypeVector %9 2
+%48 = OpTypePointer Input %47
+%49 = OpVariable %48 Input
+%53 = OpConstant %9 0.899999976
+%54 = OpConstant %9 0.200000003
+%55 = OpConstant %9 1
+%56 = OpConstantComposite %10 %53 %54 %54 %55
+%4 = OpFunction %2 None %3
+%5 = OpLabel
+%8 = OpVariable %7 Function
+%16 = OpAccessChain %15 %12 %14
+%17 = OpLoad %9 %16
+%19 = OpFSub %9 %17 %18
+%20 = OpExtInst %9 %1 FAbs %19
+%22 = OpFOrdLessThan %6 %20 %21
+OpSelectionMerge %24 None
+OpBranchConditional %22 %23 %24
+%23 = OpLabel
+%26 = OpAccessChain %15 %12 %25
+%27 = OpLoad %9 %26
+%29 = OpFSub %9 %27 %28
+%31 = OpFMod %9 %29 %30
+%33 = OpFOrdLessThan %6 %31 %21
+OpBranch %24
+%24 = OpLabel
+%34 = OpPhi %6 %22 %5 %33 %23
+OpStore %8 %34
+%35 = OpLoad %6 %8
+%37 = OpGroupNonUniformAny %6 %36 %35
+OpSelectionMerge %39 None
+OpBranchConditional %37 %38 %52
+%38 = OpLabel
+%46 = OpLoad %43 %45
+%50 = OpLoad %47 %49
+%51 = OpImageSampleImplicitLod %10 %46 %50
+OpStore %41 %51
+OpBranch %39
+%52 = OpLabel
+OpStore %41 %56
+OpBranch %39
+%39 = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(spirv, SPV_ENV_UNIVERSAL_1_3);
+ EXPECT_THAT(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_3));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr(
+ "Execution mode can only be used with the Fragment execution model"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_non_uniform_test.cpp b/third_party/SPIRV-Tools/test/val/val_non_uniform_test.cpp
index af571d3a9..530676d5e 100644
--- a/third_party/SPIRV-Tools/test/val/val_non_uniform_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_non_uniform_test.cpp
@@ -44,6 +44,10 @@ OpCapability GroupNonUniformShuffleRelative
OpCapability GroupNonUniformArithmetic
OpCapability GroupNonUniformClustered
OpCapability GroupNonUniformQuad
+OpCapability GroupNonUniformPartitionedNV
+OpCapability QuadControlKHR
+OpExtension "SPV_NV_shader_subgroup_partitioned"
+OpExtension "SPV_KHR_quad_control"
)";
ss << capabilities_and_extensions;
@@ -62,16 +66,27 @@ OpCapability GroupNonUniformQuad
%float = OpTypeFloat 32
%u32vec4 = OpTypeVector %u32 4
%u32vec3 = OpTypeVector %u32 3
+%v2bool = OpTypeVector %bool 2
+%v4float = OpTypeVector %float 4
+%struct = OpTypeStruct %int
+%v4int = OpTypeVector %int 4
%true = OpConstantTrue %bool
%false = OpConstantFalse %bool
%u32_0 = OpConstant %u32 0
+%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%u32vec4_null = OpConstantComposite %u32vec4 %u32_0 %u32_0 %u32_0 %u32_0
%u32vec3_null = OpConstantComposite %u32vec3 %u32_0 %u32_0 %u32_0
+%v2bool_false = OpConstantNull %v2bool
+%v4float_null = OpConstantNull %v4float
+%struct_null = OpConstantNull %struct
+%v4int_null = OpConstantComposite %v4int %int_0 %int_0 %int_0 %int_0
+
+%u32_undef = OpUndef %u32
%cross_device = OpConstant %u32 0
%device = OpConstant %u32 1
@@ -122,6 +137,32 @@ std::string ConvertScope(spv::Scope scope) {
}
}
+std::string ConvertMatch(const std::string& type) {
+ if (type == "%bool") {
+ return "%true";
+ } else if (type == "%u32") {
+ return "%u32_0";
+ } else if (type == "%int") {
+ return "%int_0";
+ } else if (type == "%float") {
+ return "%float_0";
+ } else if (type == "%u32vec4") {
+ return "%u32vec4_null";
+ } else if (type == "%u32vec3") {
+ return "%u32vec3_null";
+ } else if (type == "%v2bool") {
+ return "%v2bool_false";
+ } else if (type == "%v4float") {
+ return "%v4float_null";
+ } else if (type == "%struct") {
+ return "%struct_null";
+ } else if (type == "%v4int") {
+ return "%v4int_null";
+ }
+
+ return "INVALID";
+}
+
TEST_P(GroupNonUniform, Vulkan1p1) {
std::string opcode = std::get<0>(GetParam());
std::string type = std::get<1>(GetParam());
@@ -129,10 +170,20 @@ TEST_P(GroupNonUniform, Vulkan1p1) {
std::string args = std::get<3>(GetParam());
std::string error = std::get<4>(GetParam());
+ const std::string match = "match_res";
+ size_t pos = std::string::npos;
+ while ((pos = args.find(match)) != std::string::npos) {
+ const std::string replace = ConvertMatch(type);
+ args = args.substr(0, pos) + replace + args.substr(pos + match.size());
+ }
+
std::ostringstream sstr;
sstr << "%result = " << opcode << " ";
sstr << type << " ";
- sstr << ConvertScope(execution_scope) << " ";
+ if (opcode != "OpGroupNonUniformQuadAllKHR" &&
+ opcode != "OpGroupNonUniformQuadAnyKHR") {
+ sstr << ConvertScope(execution_scope) << " ";
+ }
sstr << args << "\n";
CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_VULKAN_1_1);
@@ -162,10 +213,20 @@ TEST_P(GroupNonUniform, Spirv1p3) {
std::string args = std::get<3>(GetParam());
std::string error = std::get<4>(GetParam());
+ const std::string match = "match_res";
+ size_t pos = std::string::npos;
+ while ((pos = args.find(match)) != std::string::npos) {
+ const std::string replace = ConvertMatch(type);
+ args = args.substr(0, pos) + replace + args.substr(pos + match.size());
+ }
+
std::ostringstream sstr;
sstr << "%result = " << opcode << " ";
sstr << type << " ";
- sstr << ConvertScope(execution_scope) << " ";
+ if (opcode != "OpGroupNonUniformQuadAllKHR" &&
+ opcode != "OpGroupNonUniformQuadAnyKHR") {
+ sstr << ConvertScope(execution_scope) << " ";
+ }
sstr << args << "\n";
CompileSuccessfully(GenerateShaderCode(sstr.str()), SPV_ENV_UNIVERSAL_1_3);
@@ -292,6 +353,542 @@ INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitCountBadValue, GroupNonUniform,
Values("Expected Value to be a vector of four "
"components of integer type scalar")));
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformElectGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformElect"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values(""), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformElectBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformElect"),
+ Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct"),
+ Values(spv::Scope::Subgroup), Values(""),
+ Values("Result must be a boolean scalar type")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformAnyAllGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAny",
+ "OpGroupNonUniformAll"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true", "%false"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformAnyAllBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"),
+ Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct"),
+ Values(spv::Scope::Subgroup), Values("%true"),
+ Values("Result must be a boolean scalar type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformAnyAllBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAny", "OpGroupNonUniformAll"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null",
+ "%u32vec3_null", "%v2bool_false", "%v4float_null",
+ "%struct_null"),
+ Values("Predicate must be a boolean scalar type")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformAllEqualGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAllEqual"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true", "%false"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformAllEqualBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAllEqual"),
+ Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct"),
+ Values(spv::Scope::Subgroup), Values("%true"),
+ Values("Result must be a boolean scalar type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformAllEqualBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformAllEqual"), Values("%bool"),
+ Values(spv::Scope::Subgroup), Values("%struct_null"),
+ Values("Value must be a scalar or vector of integer, "
+ "floating-point, or boolean type")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcast",
+ "OpGroupNonUniformQuadBroadcast",
+ "OpGroupNonUniformQuadSwap"),
+ Values("%bool", "%u32", "%int", "%float",
+ "%u32vec4", "%u32vec3", "%v2bool",
+ "%v4float", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("match_res %u32_0"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBroadcastShuffleBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
+ "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
+ "OpGroupNonUniformShuffleDown",
+ "OpGroupNonUniformQuadBroadcast",
+ "OpGroupNonUniformQuadSwap"),
+ Values("%void", "%struct"), Values(spv::Scope::Subgroup),
+ Values("%u32_0 %u32_0"),
+ Values("Result must be a scalar or vector of integer, "
+ "floating-point, or boolean type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBroadcastShuffleBadOperand1, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
+ "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
+ "OpGroupNonUniformShuffleDown",
+ "OpGroupNonUniformQuadBroadcast",
+ "OpGroupNonUniformQuadSwap"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%u32_0 %u32_0", "%int_0 %u32_0", "%float_0 %u32_0",
+ "%u32vec4_null %u32_0", "%u32vec3_null %u32_0",
+ "%v2bool_false %u32_0", "%v4float_null %u32_0",
+ "%struct_null %u32_0", "%v4int_null %u32_0"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBroadcastShuffleBadOperand2, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcast", "OpGroupNonUniformShuffle",
+ "OpGroupNonUniformShuffleXor", "OpGroupNonUniformShuffleUp",
+ "OpGroupNonUniformShuffleDown",
+ "OpGroupNonUniformQuadBroadcast",
+ "OpGroupNonUniformQuadSwap"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true %true", "%true %int_0", "%true %float_0",
+ "%true %u32vec4_null", "%true %u32vec3_null",
+ "%true %v4float_null", "%true %v2bool_false",
+ "%true %struct_null", "%true %v4int_null"),
+ Values("must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastShuffleOperand2NotConstant,
+ GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcast",
+ "OpGroupNonUniformQuadBroadcast",
+ "OpGroupNonUniformQuadSwap"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true %u32_undef"),
+ Values("must be a constant instruction")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBroadcastFirstGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcastFirst"),
+ Values("%bool", "%u32", "%int", "%float",
+ "%u32vec4", "%u32vec3", "%v2bool",
+ "%v4float", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("match_res"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBroadcasFirsttBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcastFirst"),
+ Values("%void", "%struct"), Values(spv::Scope::Subgroup),
+ Values("%u32_0"),
+ Values("Result must be a scalar or vector of integer, "
+ "floating-point, or boolean type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBroadcastBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBroadcastFirst"), Values("%bool"),
+ Values(spv::Scope::Subgroup),
+ Values("%u32_0", "%int_0", "%float_0", "%u32vec4_null",
+ "%u32vec3_null", "%v2bool_false", "%v4float_null",
+ "%struct_null", "%v4int_null"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallot"),
+ Values("%u32vec4"),
+ Values(spv::Scope::Subgroup),
+ Values("%true", "%false"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallot"),
+ Values("%void", "%bool", "%u32", "%int", "%float", "%u32vec3",
+ "%v2bool", "%v4float", "%struct", "%v4int"),
+ Values(spv::Scope::Subgroup), Values("%true", "%false"),
+ Values("Result must be a 4-component unsigned integer vector")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallot"),
+ Values("%u32vec4"),
+ Values(spv::Scope::Subgroup),
+ Values("%u32_0", "%int_0", "%float_0",
+ "%u32vec4_null", "%u32vec3_null",
+ "%v2bool_false", "%v4float_null",
+ "%struct_null", "%v4int_null"),
+ Values("Predicate must be a boolean scalar")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformInverseBallotGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformInverseBallot"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%u32vec4_null"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformInverseBallotBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformInverseBallot"),
+ Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct", "%v4int"),
+ Values(spv::Scope::Subgroup), Values("%u32vec4_null"),
+ Values("Result must be a boolean scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformInverseBallotBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformInverseBallot"), Values("%bool"),
+ Values(spv::Scope::Subgroup),
+ Values("%true", "%false", "%u32_0", "%int_0", "%float_0",
+ "%u32vec3_null", "%v2bool_false", "%v4float_null",
+ "%struct_null", "%v4int_null"),
+ Values("Value must be a 4-component unsigned integer vector")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotBitExtractGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotBitExtract"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%u32vec4_null %u32_0"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotBitExtractBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotBitExtract"),
+ Values("%void", "%u32", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct", "%v4int"),
+ Values(spv::Scope::Subgroup), Values("%u32vec4_null %u32_0"),
+ Values("Result must be a boolean scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotBitExtractBadOperand1, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"),
+ Values(spv::Scope::Subgroup),
+ Values("%true %u32_0", "%false %u32_0", "%u32_0 %u32_0",
+ "%int_0 %u32_0", "%float_0 %u32_0", "%u32vec3_null %u32_0",
+ "%v2bool_false %u32_0", "%v4float_null %u32_0",
+ "%struct_null %u32_0", "%v4int_null %u32_0"),
+ Values("Value must be a 4-component unsigned integer vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotBitExtractBadOperand2, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotBitExtract"), Values("%bool"),
+ Values(spv::Scope::Subgroup),
+ Values("%u32vec4_null %true", "%u32vec4_null %false",
+ "%u32vec4_null %int_0", "%u32vec4_null %float_0",
+ "%u32vec4_null %u32vec3_null", "%u32vec4_null %v2bool_false",
+ "%u32vec4_null %v4float_null", "%u32vec4_null %struct_null",
+ "%u32vec4_null %v4int_null"),
+ Values("Id must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformBallotFindGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotFindLSB",
+ "OpGroupNonUniformBallotFindMSB"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("%u32vec4_null"), Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotFindBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotFindLSB",
+ "OpGroupNonUniformBallotFindMSB"),
+ Values("%void", "%bool", "%int", "%float", "%u32vec4", "%u32vec3",
+ "%v2bool", "%v4float", "%struct", "%v4int"),
+ Values(spv::Scope::Subgroup), Values("%u32vec4_null"),
+ Values("Result must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBallotFindBadOperand, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformBallotFindLSB",
+ "OpGroupNonUniformBallotFindMSB"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("%true", "%false", "%u32_0", "%int_0", "%float_0",
+ "%u32vec3_null", "%v2bool_false", "%v4float_null",
+ "%struct_null", "%v4int_null"),
+ Values("Value must be a 4-component unsigned integer vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32", "%int", "%u32vec4", "%u32vec3", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0",
+ "PartitionedReduceNV match_res %u32vec4_null",
+ "PartitionedInclusiveScanNV match_res %u32vec4_null",
+ "PartitionedExclusiveScanNV match_res %v4int_null"),
+ Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%bool", "%float", "%v4float", "%struct"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("Result must be an integer scalar or vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticBadValue, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformSMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%int", "%u32vec4", "%u32vec3", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce %u32_0", "InclusiveScan %u32_0",
+ "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticMissingClusterSize, GroupNonUniform,
+ Combine(
+ Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
+ "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res"),
+ Values(
+ "ClusterSize must be present when Operation is ClusteredReduce")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticMissingBallot, GroupNonUniform,
+ Combine(
+ Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
+ "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("PartitionedReduceNV match_res",
+ "PartitionedInclusiveScanNV match_res",
+ "PartitionedExclusiveScanNV match_res"),
+ Values("Ballot must be present when Operation is PartitionedReduceNV, "
+ "PartitionedInclusiveScanNV, or PartitionedExclusiveScanNV")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticBadClusterSizeType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
+ "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %true",
+ "ClusteredReduce match_res %false",
+ "ClusteredReduce match_res %int_0",
+ "ClusteredReduce match_res %float_0",
+ "ClusteredReduce match_res %u32vec4_null",
+ "ClusteredReduce match_res %u32vec3_null",
+ "ClusteredReduce match_res %v2bool_false",
+ "ClusteredReduce match_res %v4float_null",
+ "ClusteredReduce match_res %struct_null",
+ "ClusteredReduce match_res %v4int_null"),
+ Values("ClusterSize must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticBadBallotType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
+ "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("PartitionedReduceNV match_res %true",
+ "PartitionedReduceNV match_res %false",
+ "PartitionedReduceNV match_res %int_0",
+ "PartitionedReduceNV match_res %float_0",
+ "PartitionedReduceNV match_res %u32_0",
+ "PartitionedReduceNV match_res %u32vec3_null",
+ "PartitionedReduceNV match_res %v2bool_false",
+ "PartitionedReduceNV match_res %v4float_null",
+ "PartitionedReduceNV match_res %struct_null"),
+ Values("Ballot must be a 4-component integer vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformIntegerArithmeticClusterSizeNotConstant, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformIAdd", "OpGroupNonUniformIMul",
+ "OpGroupNonUniformSMin", "OpGroupNonUniformUMin",
+ "OpGroupNonUniformSMax", "OpGroupNonUniformUMax",
+ "OpGroupNonUniformBitwiseAnd", "OpGroupNonUniformBitwiseOr",
+ "OpGroupNonUniformBitwiseXor"),
+ Values("%u32"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %u32_undef"),
+ Values("ClusterSize must be a constant instruction")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformUnsignedIntegerArithmeticGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
+ Values("%u32", "%u32vec4", "%u32vec3"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformUnsignedIntegerArithmeticBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
+ Values("%bool", "%int", "%float", "%v4float", "%struct", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("Result must be an unsigned integer scalar or vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformUnsignedIntegerArithmeticBadValue, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformUMin", "OpGroupNonUniformUMax"),
+ Values("%u32vec4", "%u32vec3"), Values(spv::Scope::Subgroup),
+ Values("Reduce %u32_0", "InclusiveScan %u32_0",
+ "ExclusiveScan %u32_0", "ClusteredReduce %u32_0 %u32_0"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%float", "%v4float"), Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%bool", "%u32", "%int", "%u32vec4", "%u32vec3", "%struct",
+ "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("Result must be a floating-point scalar or vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticBadValue, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%v4float"), Values(spv::Scope::Subgroup),
+ Values("Reduce %float_0", "InclusiveScan %float_0",
+ "ExclusiveScan %float_0", "ClusteredReduce %float_0 %u32_0"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticMissingClusterSize, GroupNonUniform,
+ Combine(
+ Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%float"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res"),
+ Values(
+ "ClusterSize must be present when Operation is ClusteredReduce")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticBadClusterSizeType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%float"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %true",
+ "ClusteredReduce match_res %false",
+ "ClusteredReduce match_res %int_0",
+ "ClusteredReduce match_res %float_0",
+ "ClusteredReduce match_res %u32vec4_null",
+ "ClusteredReduce match_res %u32vec3_null",
+ "ClusteredReduce match_res %v2bool_false",
+ "ClusteredReduce match_res %v4float_null",
+ "ClusteredReduce match_res %struct_null",
+ "ClusteredReduce match_res %v4int_null"),
+ Values("ClusterSize must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformFloatArithmeticClusterSizeNotConstant, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformFAdd", "OpGroupNonUniformFMul",
+ "OpGroupNonUniformFMin", "OpGroupNonUniformFMax"),
+ Values("%float"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %u32_undef"),
+ Values("ClusterSize must be a constant instruction")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticGood, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%bool", "%v2bool"), Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticBadResultType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%u32", "%int", "%float", "%u32vec4", "%u32vec3", "%struct",
+ "%v4float", "%v4int"),
+ Values(spv::Scope::Subgroup),
+ Values("Reduce match_res", "InclusiveScan match_res",
+ "ExclusiveScan match_res",
+ "ClusteredReduce match_res %u32_0"),
+ Values("Result must be a boolean scalar or vector")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticBadValue, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%v2bool"), Values(spv::Scope::Subgroup),
+ Values("Reduce %true", "InclusiveScan %true",
+ "ExclusiveScan %false", "ClusteredReduce %false %u32_0"),
+ Values("The type of Value must match the Result type")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticMissingClusterSize, GroupNonUniform,
+ Combine(
+ Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res"),
+ Values(
+ "ClusterSize must be present when Operation is ClusteredReduce")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticBadClusterSizeType, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %true",
+ "ClusteredReduce match_res %false",
+ "ClusteredReduce match_res %int_0",
+ "ClusteredReduce match_res %float_0",
+ "ClusteredReduce match_res %u32vec4_null",
+ "ClusteredReduce match_res %u32vec3_null",
+ "ClusteredReduce match_res %v2bool_false",
+ "ClusteredReduce match_res %v4float_null",
+ "ClusteredReduce match_res %struct_null",
+ "ClusteredReduce match_res %v4int_null"),
+ Values("ClusterSize must be an unsigned integer scalar")));
+
+INSTANTIATE_TEST_SUITE_P(
+ GroupNonUniformBooleanArithmeticClusterSizeNotConstant, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformLogicalAnd", "OpGroupNonUniformLogicalOr",
+ "OpGroupNonUniformLogicalXor"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("ClusteredReduce match_res %u32_undef"),
+ Values("ClusterSize must be a constant instruction")));
+
+// Subgroup scope is not actual parameter, but used for test expectations,
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformQuadAllKHR, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformQuadAllKHR"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true"), Values("")));
+
+// Subgroup scope is not actual parameter, but used for test expectations,
+INSTANTIATE_TEST_SUITE_P(GroupNonUniformQuadAnyKHR, GroupNonUniform,
+ Combine(Values("OpGroupNonUniformQuadAnyKHR"),
+ Values("%bool"), Values(spv::Scope::Subgroup),
+ Values("%true"), Values("")));
+
TEST_F(ValidateGroupNonUniform, VulkanGroupNonUniformBallotBitCountOperation) {
std::string test = R"(
OpCapability Shader
@@ -327,6 +924,146 @@ OpFunctionEnd
"be only: Reduce, InclusiveScan, or ExclusiveScan."));
}
+TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p4) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability GroupNonUniformBallot
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main" %var
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %var DescriptorSet 0
+OpDecorate %var Binding 0
+OpDecorate %struct Block
+OpMemberDecorate %struct 0 Offset 0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%subgroup = OpConstant %int 3
+%struct = OpTypeStruct %int
+%ptr_struct = OpTypePointer StorageBuffer %struct
+%ptr_int = OpTypePointer StorageBuffer %int
+%var = OpVariable %ptr_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%gep = OpAccessChain %ptr_int %var %int_0
+%ld = OpLoad %int %gep
+%broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Before SPIR-V 1.5, Id must be a constant instruction"));
+}
+
+TEST_F(ValidateGroupNonUniform, BroadcastNonConstantSpv1p5) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability GroupNonUniformBallot
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main" %var
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %var DescriptorSet 0
+OpDecorate %var Binding 0
+OpDecorate %struct Block
+OpMemberDecorate %struct 0 Offset 0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%subgroup = OpConstant %int 3
+%struct = OpTypeStruct %int
+%ptr_struct = OpTypePointer StorageBuffer %struct
+%ptr_int = OpTypePointer StorageBuffer %int
+%var = OpVariable %ptr_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%gep = OpAccessChain %ptr_int %var %int_0
+%ld = OpLoad %int %gep
+%broadcast = OpGroupNonUniformBroadcast %int %subgroup %int_0 %ld
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
+}
+
+TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p4) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability GroupNonUniformQuad
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main" %var
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %var DescriptorSet 0
+OpDecorate %var Binding 0
+OpDecorate %struct Block
+OpMemberDecorate %struct 0 Offset 0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%subgroup = OpConstant %int 3
+%struct = OpTypeStruct %int
+%ptr_struct = OpTypePointer StorageBuffer %struct
+%ptr_int = OpTypePointer StorageBuffer %int
+%var = OpVariable %ptr_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%gep = OpAccessChain %ptr_int %var %int_0
+%ld = OpLoad %int %gep
+%broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_4);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateInstructions(SPV_ENV_UNIVERSAL_1_4));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Before SPIR-V 1.5, Index must be a constant instruction"));
+}
+
+TEST_F(ValidateGroupNonUniform, QuadBroadcastNonConstantSpv1p5) {
+ const std::string text = R"(
+OpCapability Shader
+OpCapability GroupNonUniformQuad
+OpMemoryModel Logical GLSL450
+OpEntryPoint GLCompute %main "main" %var
+OpExecutionMode %main LocalSize 1 1 1
+OpDecorate %var DescriptorSet 0
+OpDecorate %var Binding 0
+OpDecorate %struct Block
+OpMemberDecorate %struct 0 Offset 0
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%subgroup = OpConstant %int 3
+%struct = OpTypeStruct %int
+%ptr_struct = OpTypePointer StorageBuffer %struct
+%ptr_int = OpTypePointer StorageBuffer %int
+%var = OpVariable %ptr_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%main = OpFunction %void None %void_fn
+%entry = OpLabel
+%gep = OpAccessChain %ptr_int %var %int_0
+%ld = OpLoad %int %gep
+%broadcast = OpGroupNonUniformQuadBroadcast %int %subgroup %int_0 %ld
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(text, SPV_ENV_UNIVERSAL_1_5);
+ EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_UNIVERSAL_1_5));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp b/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
index 58b9356ce..60f2f8911 100644
--- a/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
+++ b/third_party/SPIRV-Tools/test/val/val_ray_tracing_test.cpp
@@ -578,6 +578,95 @@ OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0
"IncomingRayPayloadKHR"));
}
+TEST_F(ValidateRayTracing, InterfaceIncomingRayPayload) {
+ const std::string body = R"(
+OpCapability RayTracingKHR
+OpExtension "SPV_KHR_ray_tracing"
+OpMemoryModel Logical GLSL450
+OpEntryPoint CallableKHR %main "main" %inData1 %inData2
+OpName %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%inData_ptr = OpTypePointer IncomingRayPayloadKHR %int
+%inData1 = OpVariable %inData_ptr IncomingRayPayloadKHR
+%inData2 = OpVariable %inData_ptr IncomingRayPayloadKHR
+%main = OpFunction %void None %func
+%label = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Entry-point has more than one variable with the "
+ "IncomingRayPayloadKHR storage class in the interface"));
+}
+
+TEST_F(ValidateRayTracing, InterfaceHitAttribute) {
+ const std::string body = R"(
+OpCapability RayTracingKHR
+OpExtension "SPV_KHR_ray_tracing"
+OpMemoryModel Logical GLSL450
+OpEntryPoint CallableKHR %main "main" %inData1 %inData2
+OpName %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%inData_ptr = OpTypePointer HitAttributeKHR %int
+%inData1 = OpVariable %inData_ptr HitAttributeKHR
+%inData2 = OpVariable %inData_ptr HitAttributeKHR
+%main = OpFunction %void None %func
+%label = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04702"));
+ EXPECT_THAT(getDiagnosticString(),
+ HasSubstr("Entry-point has more than one variable with the "
+ "HitAttributeKHR storage class in the interface"));
+}
+
+TEST_F(ValidateRayTracing, InterfaceIncomingCallableData) {
+ const std::string body = R"(
+OpCapability RayTracingKHR
+OpExtension "SPV_KHR_ray_tracing"
+OpMemoryModel Logical GLSL450
+OpEntryPoint CallableKHR %main "main" %inData1 %inData2
+OpName %main "main"
+%void = OpTypeVoid
+%func = OpTypeFunction %void
+%int = OpTypeInt 32 1
+%inData_ptr = OpTypePointer IncomingCallableDataKHR %int
+%inData1 = OpVariable %inData_ptr IncomingCallableDataKHR
+%inData2 = OpVariable %inData_ptr IncomingCallableDataKHR
+%main = OpFunction %void None %func
+%label = OpLabel
+OpReturn
+OpFunctionEnd
+)";
+
+ CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
+ EXPECT_EQ(SPV_ERROR_INVALID_DATA,
+ ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
+ EXPECT_THAT(getDiagnosticString(),
+ AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04706"));
+ EXPECT_THAT(
+ getDiagnosticString(),
+ HasSubstr("Entry-point has more than one variable with the "
+ "IncomingCallableDataKHR storage class in the interface"));
+}
+
} // namespace
} // namespace val
} // namespace spvtools
diff --git a/third_party/SPIRV-Tools/tools/fuzz/fuzz.cpp b/third_party/SPIRV-Tools/tools/fuzz/fuzz.cpp
index ca6633a6c..5f2a0080d 100644
--- a/third_party/SPIRV-Tools/tools/fuzz/fuzz.cpp
+++ b/third_party/SPIRV-Tools/tools/fuzz/fuzz.cpp
@@ -41,12 +41,6 @@ namespace {
enum class FuzzingTarget { kSpirv, kWgsl };
-// Check that the std::system function can actually be used.
-bool CheckExecuteCommand() {
- int res = std::system(nullptr);
- return res != 0;
-}
-
// Execute a command using the shell.
// Returns true if and only if the command's exit status was 0.
bool ExecuteCommand(const std::string& command) {
@@ -770,11 +764,6 @@ int main(int argc, const char** argv) {
}
break;
case FuzzActions::SHRINK: {
- if (!CheckExecuteCommand()) {
- std::cerr << "could not find shell interpreter for executing a command"
- << std::endl;
- return 1;
- }
if (!Shrink(target_env, fuzzer_options, validator_options, binary_in,
initial_facts, shrink_transformations_file,
shrink_temp_file_prefix, interestingness_test, &binary_out,
diff --git a/third_party/SPIRV-Tools/tools/io.h b/third_party/SPIRV-Tools/tools/io.h
index 8bbee3a0d..a48e3c325 100644
--- a/third_party/SPIRV-Tools/tools/io.h
+++ b/third_party/SPIRV-Tools/tools/io.h
@@ -144,6 +144,7 @@ class OutputFile {
~OutputFile() {
if (fp_ == stdout) {
+ fflush(stdout);
SET_STDOUT_MODE(old_mode_);
} else if (fp_ != nullptr) {
fclose(fp_);
diff --git a/third_party/SPIRV-Tools/tools/link/linker.cpp b/third_party/SPIRV-Tools/tools/link/linker.cpp
index 381d8b9b5..f3898aab0 100644
--- a/third_party/SPIRV-Tools/tools/link/linker.cpp
+++ b/third_party/SPIRV-Tools/tools/link/linker.cpp
@@ -59,6 +59,13 @@ Options (in lexicographical order):
NOTE: The SPIR-V version used by the linked binary module
depends only on the version of the inputs, and is not affected
by this option.
+ --use-highest-version
+ Upgrade the output SPIR-V version to the highest of the input
+ files, instead of requiring all of them to have the same
+ version.
+ NOTE: If one of the older input files uses an instruction that
+ is deprecated in the highest SPIR-V version, the output will
+ be invalid.
--verify-ids
Verify that IDs in the resulting modules are truly unique.
--version
@@ -78,6 +85,7 @@ FLAG_LONG_bool( create_library, /* default_value= */ false,
FLAG_LONG_bool( allow_partial_linkage, /* default_value= */ false, /* required= */ false);
FLAG_SHORT_string(o, /* default_value= */ "", /* required= */ false);
FLAG_LONG_string( target_env, /* default_value= */ kDefaultEnvironment, /* required= */ false);
+FLAG_LONG_bool( use_highest_version, /* default_value= */ false, /* required= */ false);
// clang-format on
int main(int, const char* argv[]) {
@@ -120,6 +128,7 @@ int main(int, const char* argv[]) {
options.SetAllowPartialLinkage(flags::allow_partial_linkage.value());
options.SetCreateLibrary(flags::create_library.value());
options.SetVerifyIds(flags::verify_ids.value());
+ options.SetUseHighestVersion(flags::use_highest_version.value());
if (inFiles.empty()) {
fprintf(stderr, "error: No input file specified\n");
diff --git a/third_party/SPIRV-Tools/tools/opt/opt.cpp b/third_party/SPIRV-Tools/tools/opt/opt.cpp
index ce2103ca8..f8456d714 100644
--- a/third_party/SPIRV-Tools/tools/opt/opt.cpp
+++ b/third_party/SPIRV-Tools/tools/opt/opt.cpp
@@ -335,6 +335,12 @@ Options (in lexicographical order):)",
These conditions are guaranteed to be met after running
dead-branch elimination.)");
printf(R"(
+ --modify-maximal-reconvergence=[add|remove]
+ Add or remove the MaximallyReconvergesKHR execution mode to all
+ entry points in the module.
+ Note: when adding the execution mode, no attempt is made to
+ determine if any ray tracing repack instructions are used.)");
+ printf(R"(
--loop-unswitch
Hoists loop-invariant conditionals out of loops by duplicating
the loop on each branch of the conditional and adjusting each
@@ -392,6 +398,11 @@ Options (in lexicographical order):)",
Ensure that the optimizer preserves all bindings declared within
the module, even when those bindings are unused.)");
printf(R"(
+ --preserve-interface
+ Ensure that input and output variables are not removed from the
+ shader, even if they are unused. Note that this option applies to
+ all passes that will be run regardless of the order of the flags.)");
+ printf(R"(
--preserve-spec-constants
Ensure that the optimizer preserves all specialization constants declared
within the module, even when those constants are unused.)");
@@ -496,6 +507,10 @@ Options (in lexicographical order):)",
covers reflection information defined by
SPV_GOOGLE_hlsl_functionality1 and SPV_KHR_non_semantic_info)");
printf(R"(
+ --switch-descriptorset=<from>:<to>
+ Switch any DescriptoSet decorations using the value <from> to
+ the new value <to>.)");
+ printf(R"(
--target-env=<env>
Set the target environment. Without this flag the target
environment defaults to spv1.5. <env> must be one of
@@ -510,6 +525,10 @@ Options (in lexicographical order):)",
USR/SYS time are returned by getrusage() and can have a small
error.)");
printf(R"(
+ --trim-capabilities
+ Remove unnecessary capabilities and extensions declared within the
+ module.)");
+ printf(R"(
--upgrade-memory-model
Upgrades the Logical GLSL450 memory model to Logical VulkanKHR.
Transforms memory, image, atomic and barrier operations to conform
@@ -697,6 +716,7 @@ OptStatus ParseFlags(int argc, const char** argv,
spvtools::ValidatorOptions* validator_options,
spvtools::OptimizerOptions* optimizer_options) {
std::vector<std::string> pass_flags;
+ bool preserve_interface = true;
for (int argi = 1; argi < argc; ++argi) {
const char* cur_arg = argv[argi];
if ('-' == cur_arg[0]) {
@@ -786,6 +806,8 @@ OptStatus ParseFlags(int argc, const char** argv,
validator_options->SetSkipBlockLayout(true);
} else if (0 == strcmp(cur_arg, "--relax-struct-store")) {
validator_options->SetRelaxStructStore(true);
+ } else if (0 == strcmp(cur_arg, "--preserve-interface")) {
+ preserve_interface = true;
} else {
// Some passes used to accept the form '--pass arg', canonicalize them
// to '--pass=arg'.
@@ -808,7 +830,7 @@ OptStatus ParseFlags(int argc, const char** argv,
}
}
- if (!optimizer->RegisterPassesFromFlags(pass_flags)) {
+ if (!optimizer->RegisterPassesFromFlags(pass_flags, preserve_interface)) {
return {OPT_STOP, 1};
}
diff --git a/third_party/SPIRV-Tools/tools/reduce/reduce.cpp b/third_party/SPIRV-Tools/tools/reduce/reduce.cpp
index 37600543a..959f5a2f2 100644
--- a/third_party/SPIRV-Tools/tools/reduce/reduce.cpp
+++ b/third_party/SPIRV-Tools/tools/reduce/reduce.cpp
@@ -14,6 +14,7 @@
#include <cassert>
#include <cerrno>
+#include <cstdlib>
#include <cstring>
#include <functional>
#include <sstream>
@@ -29,12 +30,6 @@
namespace {
-// Check that the std::system function can actually be used.
-bool CheckExecuteCommand() {
- int res = std::system(nullptr);
- return res != 0;
-}
-
// Execute a command using the shell.
// Returns true if and only if the command's exit status was 0.
bool ExecuteCommand(const std::string& command) {
@@ -282,12 +277,6 @@ int main(int argc, const char** argv) {
return status.code;
}
- if (!CheckExecuteCommand()) {
- std::cerr << "could not find shell interpreter for executing a command"
- << std::endl;
- return 2;
- }
-
spvtools::reduce::Reducer reducer(target_env);
std::stringstream joined;
diff --git a/third_party/SPIRV-Tools/tools/sva/package.json b/third_party/SPIRV-Tools/tools/sva/package.json
index 3072d4cc8..15feacae9 100644
--- a/third_party/SPIRV-Tools/tools/sva/package.json
+++ b/third_party/SPIRV-Tools/tools/sva/package.json
@@ -15,11 +15,11 @@
"bundle": "rollup -c"
},
"devDependencies": {
- "chai": "^4.2.0",
- "eslint": "^6.3.0",
+ "chai": "^4.3.7",
+ "eslint": "^8.41.0",
"esm": "^3.2.25",
- "mocha": "^6.2.0",
- "rollup": "^1.21.4",
- "serve": "^11.1.0"
+ "mocha": "^10.2.0",
+ "rollup": "^3.23.0",
+ "serve": "^14.2.0"
}
}
diff --git a/third_party/SPIRV-Tools/tools/sva/src/spirv.data.js b/third_party/SPIRV-Tools/tools/sva/src/spirv.data.js
index ba969d86b..67c0966cd 100644
--- a/third_party/SPIRV-Tools/tools/sva/src/spirv.data.js
+++ b/third_party/SPIRV-Tools/tools/sva/src/spirv.data.js
@@ -4376,6 +4376,9 @@ export default {
"ShaderClockKHR": {
"value": 5055
},
+ "QuadControlKHR": {
+ "value": 5087
+ },
"FragmentFullyCoveredEXT": {
"value": 5265
},
diff --git a/third_party/SPIRV-Tools/tools/sva/yarn.lock b/third_party/SPIRV-Tools/tools/sva/yarn.lock
index 2dc95d8a4..eed94ced1 100644
--- a/third_party/SPIRV-Tools/tools/sva/yarn.lock
+++ b/third_party/SPIRV-Tools/tools/sva/yarn.lock
@@ -2,158 +2,206 @@
# yarn lockfile v1
-"@babel/code-frame@^7.0.0":
- version "7.5.5"
- resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d"
- integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==
+"@eslint-community/eslint-utils@^4.2.0":
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59"
+ integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
dependencies:
- "@babel/highlight" "^7.0.0"
+ eslint-visitor-keys "^3.3.0"
-"@babel/highlight@^7.0.0":
- version "7.5.0"
- resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540"
- integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==
- dependencies:
- chalk "^2.0.0"
- esutils "^2.0.2"
- js-tokens "^4.0.0"
-
-"@types/estree@0.0.39":
- version "0.0.39"
- resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
- integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
+"@eslint-community/regexpp@^4.4.0":
+ version "4.5.1"
+ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884"
+ integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==
-"@types/node@^12.7.5":
- version "12.7.5"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f"
- integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==
+"@eslint/eslintrc@^2.0.3":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331"
+ integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==
+ dependencies:
+ ajv "^6.12.4"
+ debug "^4.3.2"
+ espree "^9.5.2"
+ globals "^13.19.0"
+ ignore "^5.2.0"
+ import-fresh "^3.2.1"
+ js-yaml "^4.1.0"
+ minimatch "^3.1.2"
+ strip-json-comments "^3.1.1"
+
+"@eslint/js@8.41.0":
+ version "8.41.0"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.41.0.tgz#080321c3b68253522f7646b55b577dd99d2950b3"
+ integrity sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==
+
+"@humanwhocodes/config-array@^0.11.8":
+ version "0.11.8"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9"
+ integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.1"
+ debug "^4.1.1"
+ minimatch "^3.0.5"
+
+"@humanwhocodes/module-importer@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
-"@zeit/schemas@2.6.0":
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.6.0.tgz#004e8e553b4cd53d538bd38eac7bcbf58a867fe3"
- integrity sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==
+"@humanwhocodes/object-schema@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
-accepts@~1.3.5:
- version "1.3.7"
- resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
- integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
- mime-types "~2.1.24"
- negotiator "0.6.2"
+ "@nodelib/fs.stat" "2.0.5"
+ run-parallel "^1.1.9"
-acorn-jsx@^5.0.2:
- version "5.0.2"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f"
- integrity sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==
-
-acorn@^7.0.0:
- version "7.1.1"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
- integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
+"@nodelib/fs.stat@2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
-ajv@6.5.3:
- version "6.5.3"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.3.tgz#71a569d189ecf4f4f321224fecb166f071dd90f9"
- integrity sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==
+"@nodelib/fs.walk@^1.2.8":
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
- fast-deep-equal "^2.0.1"
- fast-json-stable-stringify "^2.0.0"
- json-schema-traverse "^0.4.1"
+ "@nodelib/fs.scandir" "2.1.5"
+ fastq "^1.6.0"
+
+"@zeit/schemas@2.29.0":
+ version "2.29.0"
+ resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.29.0.tgz#a59ae6ebfdf4ddc66a876872dd736baa58b6696c"
+ integrity sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA==
+
+accepts@~1.3.5:
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
+ integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
+ dependencies:
+ mime-types "~2.1.34"
+ negotiator "0.6.3"
+
+acorn-jsx@^5.3.2:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn@^8.8.0:
+ version "8.8.2"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
+ integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
+
+ajv@8.11.0:
+ version "8.11.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
+ integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
+ dependencies:
+ fast-deep-equal "^3.1.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
uri-js "^4.2.2"
-ajv@^6.10.0, ajv@^6.10.2:
- version "6.10.2"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
- integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
+ajv@^6.10.0, ajv@^6.12.4:
+ version "6.12.6"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
+ integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
- fast-deep-equal "^2.0.1"
+ fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-ansi-align@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
- integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=
+ansi-align@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
+ integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
dependencies:
- string-width "^2.0.0"
+ string-width "^4.1.0"
-ansi-colors@3.2.3:
- version "3.2.3"
- resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813"
- integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==
+ansi-colors@4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
+ integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
-ansi-escapes@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
- integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
-ansi-regex@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
- integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
+ansi-regex@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
+ integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
-ansi-regex@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
- integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
-ansi-regex@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
- integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
+ansi-styles@^6.1.0:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
+ integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
- version "3.2.1"
- resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
- integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+anymatch@~3.1.2:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
+ integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
dependencies:
- color-convert "^1.9.0"
+ normalize-path "^3.0.0"
+ picomatch "^2.0.4"
-arch@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e"
- integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==
+arch@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
+ integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
-arg@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/arg/-/arg-2.0.0.tgz#c06e7ff69ab05b3a4a03ebe0407fac4cba657545"
- integrity sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==
+arg@5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
+ integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
-argparse@^1.0.7:
- version "1.0.10"
- resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
- integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
- dependencies:
- sprintf-js "~1.0.2"
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
assertion-error@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
-astral-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
- integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
-
balanced-match@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
- integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
-
-boxen@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
- integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==
- dependencies:
- ansi-align "^2.0.0"
- camelcase "^4.0.0"
- chalk "^2.0.1"
- cli-boxes "^1.0.0"
- string-width "^2.0.0"
- term-size "^1.2.0"
- widest-line "^2.0.0"
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+binary-extensions@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
+ integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
+
+boxen@7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32"
+ integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==
+ dependencies:
+ ansi-align "^3.0.1"
+ camelcase "^7.0.0"
+ chalk "^5.0.1"
+ cli-boxes "^3.0.0"
+ string-width "^5.1.2"
+ type-fest "^2.13.0"
+ widest-line "^4.0.1"
+ wrap-ansi "^8.0.1"
brace-expansion@^1.1.7:
version "1.1.11"
@@ -163,6 +211,20 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
+brace-expansion@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
+ integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
+ dependencies:
+ balanced-match "^1.0.0"
+
+braces@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+ integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+ dependencies:
+ fill-range "^7.0.1"
+
browser-stdout@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
@@ -171,163 +233,154 @@ browser-stdout@1.3.1:
bytes@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
- integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=
+ integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-camelcase@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
- integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
+camelcase@^6.0.0:
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
+ integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-camelcase@^5.0.0:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
- integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+camelcase@^7.0.0:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048"
+ integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==
-chai@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5"
- integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==
+chai@^4.3.7:
+ version "4.3.7"
+ resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51"
+ integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==
dependencies:
assertion-error "^1.1.0"
check-error "^1.0.2"
- deep-eql "^3.0.1"
+ deep-eql "^4.1.2"
get-func-name "^2.0.0"
- pathval "^1.1.0"
+ loupe "^2.3.1"
+ pathval "^1.1.1"
type-detect "^4.0.5"
-chalk@2.4.1:
- version "2.4.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
- integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
+chalk-template@0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b"
+ integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==
dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
+ chalk "^4.1.2"
-chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2:
- version "2.4.2"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
- integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+chalk@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6"
+ integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==
+
+chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
- ansi-styles "^3.2.1"
- escape-string-regexp "^1.0.5"
- supports-color "^5.3.0"
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
-chardet@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
- integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
+chalk@^5.0.1:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3"
+ integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
- integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
-
-cli-boxes@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
- integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM=
-
-cli-cursor@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
- integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=
- dependencies:
- restore-cursor "^2.0.0"
-
-cli-width@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
- integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
+ integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
+
+chokidar@3.5.3:
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
+ integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
+cli-boxes@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145"
+ integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==
-clipboardy@1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef"
- integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==
+clipboardy@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092"
+ integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==
dependencies:
- arch "^2.1.0"
- execa "^0.8.0"
+ arch "^2.2.0"
+ execa "^5.1.1"
+ is-wsl "^2.2.0"
-cliui@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49"
- integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
+cliui@^7.0.2:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
+ integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
dependencies:
- string-width "^2.1.1"
- strip-ansi "^4.0.0"
- wrap-ansi "^2.0.0"
-
-code-point-at@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
- integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+ string-width "^4.2.0"
+ strip-ansi "^6.0.0"
+ wrap-ansi "^7.0.0"
-color-convert@^1.9.0:
- version "1.9.3"
- resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
- integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
- color-name "1.1.3"
+ color-name "~1.1.4"
-color-name@1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
- integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-compressible@~2.0.14:
- version "2.0.17"
- resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.17.tgz#6e8c108a16ad58384a977f3a482ca20bff2f38c1"
- integrity sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==
+compressible@~2.0.16:
+ version "2.0.18"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
+ integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
dependencies:
- mime-db ">= 1.40.0 < 2"
+ mime-db ">= 1.43.0 < 2"
-compression@1.7.3:
- version "1.7.3"
- resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db"
- integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==
+compression@1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
+ integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
dependencies:
accepts "~1.3.5"
bytes "3.0.0"
- compressible "~2.0.14"
+ compressible "~2.0.16"
debug "2.6.9"
- on-headers "~1.0.1"
+ on-headers "~1.0.2"
safe-buffer "5.1.2"
vary "~1.1.2"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
- integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+ integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
content-disposition@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
- integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ=
-
-cross-spawn@^5.0.1:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
- integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
- dependencies:
- lru-cache "^4.0.1"
- shebang-command "^1.2.0"
- which "^1.2.9"
+ integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==
-cross-spawn@^6.0.0, cross-spawn@^6.0.5:
- version "6.0.5"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
- integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
+cross-spawn@^7.0.2, cross-spawn@^7.0.3:
+ version "7.0.3"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
+ integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
dependencies:
- nice-try "^1.0.4"
- path-key "^2.0.1"
- semver "^5.5.0"
- shebang-command "^1.2.0"
- which "^1.2.9"
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
debug@2.6.9:
version "2.6.9"
@@ -336,29 +389,22 @@ debug@2.6.9:
dependencies:
ms "2.0.0"
-debug@3.2.6:
- version "3.2.6"
- resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
- integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
- dependencies:
- ms "^2.1.1"
-
-debug@^4.0.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
- integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
+debug@4.3.4, debug@^4.1.1, debug@^4.3.2:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
+ integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
- ms "^2.1.1"
+ ms "2.1.2"
-decamelize@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
- integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+decamelize@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
+ integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
-deep-eql@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df"
- integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==
+deep-eql@^4.1.2:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d"
+ integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==
dependencies:
type-detect "^4.0.0"
@@ -367,22 +413,15 @@ deep-extend@^0.6.0:
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
-deep-is@~0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
- integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-
-define-properties@^1.1.2, define-properties@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
- integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
- dependencies:
- object-keys "^1.0.12"
+deep-is@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
-diff@3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
- integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
+diff@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
+ integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
doctrine@^3.0.0:
version "3.0.0"
@@ -391,319 +430,254 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
-emoji-regex@^7.0.1:
- version "7.0.3"
- resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
- integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
-
-end-of-stream@^1.1.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43"
- integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==
- dependencies:
- once "^1.4.0"
-
-es-abstract@^1.5.1:
- version "1.14.2"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.2.tgz#7ce108fad83068c8783c3cdf62e504e084d8c497"
- integrity sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==
- dependencies:
- es-to-primitive "^1.2.0"
- function-bind "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.0"
- is-callable "^1.1.4"
- is-regex "^1.0.4"
- object-inspect "^1.6.0"
- object-keys "^1.1.1"
- string.prototype.trimleft "^2.0.0"
- string.prototype.trimright "^2.0.0"
-
-es-to-primitive@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
- integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==
- dependencies:
- is-callable "^1.1.4"
- is-date-object "^1.0.1"
- is-symbol "^1.0.2"
-
-escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
- integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+eastasianwidth@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
+ integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
-eslint-scope@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
- integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
- dependencies:
- esrecurse "^4.1.0"
- estraverse "^4.1.1"
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
-eslint-utils@^1.4.2:
- version "1.4.2"
- resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.2.tgz#166a5180ef6ab7eb462f162fd0e6f2463d7309ab"
- integrity sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==
- dependencies:
- eslint-visitor-keys "^1.0.0"
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
-eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
- integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
+escalade@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
+ integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
-eslint@^6.3.0:
- version "6.4.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.4.0.tgz#5aa9227c3fbe921982b2eda94ba0d7fae858611a"
- integrity sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==
- dependencies:
- "@babel/code-frame" "^7.0.0"
+escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
+eslint-scope@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b"
+ integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==
+ dependencies:
+ esrecurse "^4.3.0"
+ estraverse "^5.2.0"
+
+eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1:
+ version "3.4.1"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994"
+ integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==
+
+eslint@^8.41.0:
+ version "8.41.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.41.0.tgz#3062ca73363b4714b16dbc1e60f035e6134b6f1c"
+ integrity sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==
+ dependencies:
+ "@eslint-community/eslint-utils" "^4.2.0"
+ "@eslint-community/regexpp" "^4.4.0"
+ "@eslint/eslintrc" "^2.0.3"
+ "@eslint/js" "8.41.0"
+ "@humanwhocodes/config-array" "^0.11.8"
+ "@humanwhocodes/module-importer" "^1.0.1"
+ "@nodelib/fs.walk" "^1.2.8"
ajv "^6.10.0"
- chalk "^2.1.0"
- cross-spawn "^6.0.5"
- debug "^4.0.1"
+ chalk "^4.0.0"
+ cross-spawn "^7.0.2"
+ debug "^4.3.2"
doctrine "^3.0.0"
- eslint-scope "^5.0.0"
- eslint-utils "^1.4.2"
- eslint-visitor-keys "^1.1.0"
- espree "^6.1.1"
- esquery "^1.0.1"
+ escape-string-regexp "^4.0.0"
+ eslint-scope "^7.2.0"
+ eslint-visitor-keys "^3.4.1"
+ espree "^9.5.2"
+ esquery "^1.4.2"
esutils "^2.0.2"
- file-entry-cache "^5.0.1"
- functional-red-black-tree "^1.0.1"
- glob-parent "^5.0.0"
- globals "^11.7.0"
- ignore "^4.0.6"
+ fast-deep-equal "^3.1.3"
+ file-entry-cache "^6.0.1"
+ find-up "^5.0.0"
+ glob-parent "^6.0.2"
+ globals "^13.19.0"
+ graphemer "^1.4.0"
+ ignore "^5.2.0"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
- inquirer "^6.4.1"
is-glob "^4.0.0"
- js-yaml "^3.13.1"
+ is-path-inside "^3.0.3"
+ js-yaml "^4.1.0"
json-stable-stringify-without-jsonify "^1.0.1"
- levn "^0.3.0"
- lodash "^4.17.14"
- minimatch "^3.0.4"
- mkdirp "^0.5.1"
+ levn "^0.4.1"
+ lodash.merge "^4.6.2"
+ minimatch "^3.1.2"
natural-compare "^1.4.0"
- optionator "^0.8.2"
- progress "^2.0.0"
- regexpp "^2.0.1"
- semver "^6.1.2"
- strip-ansi "^5.2.0"
- strip-json-comments "^3.0.1"
- table "^5.2.3"
+ optionator "^0.9.1"
+ strip-ansi "^6.0.1"
+ strip-json-comments "^3.1.0"
text-table "^0.2.0"
- v8-compile-cache "^2.0.3"
esm@^3.2.25:
version "3.2.25"
resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10"
integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==
-espree@^6.1.1:
- version "6.1.1"
- resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.1.tgz#7f80e5f7257fc47db450022d723e356daeb1e5de"
- integrity sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==
+espree@^9.5.2:
+ version "9.5.2"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b"
+ integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==
dependencies:
- acorn "^7.0.0"
- acorn-jsx "^5.0.2"
- eslint-visitor-keys "^1.1.0"
-
-esprima@^4.0.0:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
- integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+ acorn "^8.8.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^3.4.1"
-esquery@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708"
- integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==
+esquery@^1.4.2:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b"
+ integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==
dependencies:
- estraverse "^4.0.0"
+ estraverse "^5.1.0"
-esrecurse@^4.1.0:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf"
- integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==
+esrecurse@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
+ integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
- estraverse "^4.1.0"
+ estraverse "^5.2.0"
-estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
- integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
+estraverse@^5.1.0, estraverse@^5.2.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-execa@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
- integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
- dependencies:
- cross-spawn "^5.0.1"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-execa@^0.8.0:
- version "0.8.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da"
- integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=
- dependencies:
- cross-spawn "^5.0.1"
- get-stream "^3.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-execa@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
- integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==
- dependencies:
- cross-spawn "^6.0.0"
- get-stream "^4.0.0"
- is-stream "^1.1.0"
- npm-run-path "^2.0.0"
- p-finally "^1.0.0"
- signal-exit "^3.0.0"
- strip-eof "^1.0.0"
-
-external-editor@^3.0.3:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495"
- integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==
- dependencies:
- chardet "^0.7.0"
- iconv-lite "^0.4.24"
- tmp "^0.0.33"
-
-fast-deep-equal@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
- integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
+execa@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.0"
+ human-signals "^2.1.0"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.1"
+ onetime "^5.1.2"
+ signal-exit "^3.0.3"
+ strip-final-newline "^2.0.0"
+
+fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-json-stable-stringify@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
- integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+ integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
-fast-levenshtein@~2.0.4:
+fast-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
- integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
+ integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fast-url-parser@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d"
- integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=
+ integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==
dependencies:
punycode "^1.3.2"
-figures@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962"
- integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=
+fastq@^1.6.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a"
+ integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==
dependencies:
- escape-string-regexp "^1.0.5"
+ reusify "^1.0.4"
-file-entry-cache@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c"
- integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==
+file-entry-cache@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027"
+ integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==
dependencies:
- flat-cache "^2.0.1"
+ flat-cache "^3.0.4"
-find-up@3.0.0, find-up@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
- integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
+fill-range@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+ integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
- locate-path "^3.0.0"
+ to-regex-range "^5.0.1"
-flat-cache@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0"
- integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==
+find-up@5.0.0, find-up@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
+ integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
dependencies:
- flatted "^2.0.0"
- rimraf "2.6.3"
- write "1.0.3"
+ locate-path "^6.0.0"
+ path-exists "^4.0.0"
-flat@^4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2"
- integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==
+flat-cache@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11"
+ integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==
dependencies:
- is-buffer "~2.0.3"
+ flatted "^3.1.0"
+ rimraf "^3.0.2"
-flatted@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08"
- integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==
+flat@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
+ integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
+
+flatted@^3.1.0:
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
+ integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
- integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-
-function-bind@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
- integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-
-functional-red-black-tree@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
- integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
+ integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
-get-caller-file@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
- integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
+fsevents@~2.3.2:
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
+ integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
-get-caller-file@^2.0.1:
+get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-func-name@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
- integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
+ integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
-get-stream@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
- integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
+get-stream@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
-get-stream@^4.0.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
- integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==
+glob-parent@^6.0.2:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
+ integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
- pump "^3.0.0"
+ is-glob "^4.0.3"
-glob-parent@^5.0.0:
+glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
-glob@7.1.3:
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
- integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
+glob@7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
+ integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
@@ -713,65 +687,53 @@ glob@7.1.3:
path-is-absolute "^1.0.0"
glob@^7.1.3:
- version "7.1.4"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255"
- integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
+ integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "^3.0.4"
+ minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
-globals@^11.7.0:
- version "11.12.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
- integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-
-growl@1.10.5:
- version "1.10.5"
- resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
- integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
-
-has-flag@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
- integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+globals@^13.19.0:
+ version "13.20.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82"
+ integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
+ dependencies:
+ type-fest "^0.20.2"
-has-symbols@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
- integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
+graphemer@^1.4.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
+ integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
-has@^1.0.1, has@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
- integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
- dependencies:
- function-bind "^1.1.1"
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
he@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
-iconv-lite@^0.4.24:
- version "0.4.24"
- resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
- integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
- dependencies:
- safer-buffer ">= 2.1.2 < 3"
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
-ignore@^4.0.6:
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
- integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
+ignore@^5.2.0:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
+ integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
-import-fresh@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118"
- integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==
+import-fresh@^3.0.0, import-fresh@^3.2.1:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
+ integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
@@ -779,12 +741,12 @@ import-fresh@^3.0.0:
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
- integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
+ integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
- integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
+ integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
@@ -795,193 +757,147 @@ inherits@2:
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@~1.3.0:
- version "1.3.7"
- resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
- integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
-
-inquirer@^6.4.1:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
- integrity sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==
- dependencies:
- ansi-escapes "^3.2.0"
- chalk "^2.4.2"
- cli-cursor "^2.1.0"
- cli-width "^2.0.0"
- external-editor "^3.0.3"
- figures "^2.0.0"
- lodash "^4.17.12"
- mute-stream "0.0.7"
- run-async "^2.2.0"
- rxjs "^6.4.0"
- string-width "^2.1.0"
- strip-ansi "^5.1.0"
- through "^2.3.6"
-
-invert-kv@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
- integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
-
-is-buffer@~2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725"
- integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==
+ version "1.3.8"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
+ integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
-is-callable@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
- integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
+is-binary-path@~2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
+ integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
+ dependencies:
+ binary-extensions "^2.0.0"
-is-date-object@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
- integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=
+is-docker@^2.0.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
+ integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
- integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+ integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
-is-fullwidth-code-point@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
- integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
- dependencies:
- number-is-nan "^1.0.0"
-
-is-fullwidth-code-point@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
- integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
-is-glob@^4.0.0, is-glob@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
- integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
+is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
-is-promise@^2.1.0:
+is-number@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+ integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+is-path-inside@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
+ integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+
+is-plain-obj@^2.1.0:
version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
- integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
+ integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
-is-regex@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
- integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=
- dependencies:
- has "^1.0.1"
+is-port-reachable@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-4.0.0.tgz#dac044091ef15319c8ab2f34604d8794181f8c2d"
+ integrity sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==
-is-stream@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
- integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
-is-symbol@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
- integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==
+is-unicode-supported@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
+ integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+
+is-wsl@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
+ integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
- has-symbols "^1.0.0"
+ is-docker "^2.0.0"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
- integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
-js-tokens@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
- integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-
-js-yaml@3.13.1, js-yaml@^3.13.1:
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
- integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
+js-yaml@4.1.0, js-yaml@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
+ argparse "^2.0.1"
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
- integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=
+ integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
-lcid@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf"
- integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==
- dependencies:
- invert-kv "^2.0.0"
-
-levn@^0.3.0, levn@~0.3.0:
- version "0.3.0"
- resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
- integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
- dependencies:
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
-
-locate-path@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
- integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
+levn@^0.4.1:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
+ integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
dependencies:
- p-locate "^3.0.0"
- path-exists "^3.0.0"
-
-lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14:
- version "4.17.21"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
- integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
+ prelude-ls "^1.2.1"
+ type-check "~0.4.0"
-log-symbols@2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
- integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
+locate-path@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
+ integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
dependencies:
- chalk "^2.0.1"
+ p-locate "^5.0.0"
-lru-cache@^4.0.1:
- version "4.1.5"
- resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
- integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
- dependencies:
- pseudomap "^1.0.2"
- yallist "^2.1.2"
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-map-age-cleaner@^0.1.1:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a"
- integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==
+log-symbols@4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
+ integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
dependencies:
- p-defer "^1.0.0"
+ chalk "^4.1.0"
+ is-unicode-supported "^0.1.0"
-mem@^4.0.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
- integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==
+loupe@^2.3.1:
+ version "2.3.6"
+ resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53"
+ integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==
dependencies:
- map-age-cleaner "^0.1.1"
- mimic-fn "^2.0.0"
- p-is-promise "^2.0.0"
+ get-func-name "^2.0.0"
-mime-db@1.40.0:
- version "1.40.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32"
- integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==
+merge-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
+ integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-"mime-db@>= 1.40.0 < 2":
- version "1.41.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.41.0.tgz#9110408e1f6aa1b34aef51f2c9df3caddf46b6a0"
- integrity sha512-B5gxBI+2K431XW8C2rcc/lhppbuji67nf9v39eH8pkWoZDxnAL0PxdpH32KYRScniF8qDHBDlI+ipgg5WrCUYw==
+mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
+ version "1.52.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
+ integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-db@~1.33.0:
version "1.33.0"
@@ -995,237 +911,150 @@ mime-types@2.1.18:
dependencies:
mime-db "~1.33.0"
-mime-types@~2.1.24:
- version "2.1.24"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81"
- integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==
+mime-types@~2.1.34:
+ version "2.1.35"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
+ integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
- mime-db "1.40.0"
-
-mimic-fn@^1.0.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
- integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
+ mime-db "1.52.0"
-mimic-fn@^2.0.0:
+mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-minimatch@3.0.4, minimatch@^3.0.4:
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
- integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
+minimatch@3.1.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
+ integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
-minimist@0.0.8:
- version "0.0.8"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
- integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
+minimatch@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
+ integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
+ dependencies:
+ brace-expansion "^2.0.1"
minimist@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
- integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
-
-mkdirp@0.5.1, mkdirp@^0.5.1:
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
- integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
- dependencies:
- minimist "0.0.8"
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
+ integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-mocha@^6.2.0:
- version "6.2.0"
- resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.0.tgz#f896b642843445d1bb8bca60eabd9206b8916e56"
- integrity sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==
+mocha@^10.2.0:
+ version "10.2.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8"
+ integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==
dependencies:
- ansi-colors "3.2.3"
+ ansi-colors "4.1.1"
browser-stdout "1.3.1"
- debug "3.2.6"
- diff "3.5.0"
- escape-string-regexp "1.0.5"
- find-up "3.0.0"
- glob "7.1.3"
- growl "1.10.5"
+ chokidar "3.5.3"
+ debug "4.3.4"
+ diff "5.0.0"
+ escape-string-regexp "4.0.0"
+ find-up "5.0.0"
+ glob "7.2.0"
he "1.2.0"
- js-yaml "3.13.1"
- log-symbols "2.2.0"
- minimatch "3.0.4"
- mkdirp "0.5.1"
- ms "2.1.1"
- node-environment-flags "1.0.5"
- object.assign "4.1.0"
- strip-json-comments "2.0.1"
- supports-color "6.0.0"
- which "1.3.1"
- wide-align "1.1.3"
- yargs "13.2.2"
- yargs-parser "13.0.0"
- yargs-unparser "1.5.0"
+ js-yaml "4.1.0"
+ log-symbols "4.1.0"
+ minimatch "5.0.1"
+ ms "2.1.3"
+ nanoid "3.3.3"
+ serialize-javascript "6.0.0"
+ strip-json-comments "3.1.1"
+ supports-color "8.1.1"
+ workerpool "6.2.1"
+ yargs "16.2.0"
+ yargs-parser "20.2.4"
+ yargs-unparser "2.0.0"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
- integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
+ integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
-ms@2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
- integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
-
-ms@^2.1.1:
+ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
-mute-stream@0.0.7:
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
- integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=
+ms@2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nanoid@3.3.3:
+ version "3.3.3"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
+ integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
- integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
+ integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
-negotiator@0.6.2:
- version "0.6.2"
- resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
- integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+negotiator@0.6.3:
+ version "0.6.3"
+ resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
+ integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
-nice-try@^1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
- integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-
-node-environment-flags@1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a"
- integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==
- dependencies:
- object.getownpropertydescriptors "^2.0.3"
- semver "^5.7.0"
-
-npm-run-path@^2.0.0:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f"
- integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
- dependencies:
- path-key "^2.0.0"
-
-number-is-nan@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
- integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
-
-object-inspect@^1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
- integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==
-
-object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
- integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
-
-object.assign@4.1.0:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
- integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
- dependencies:
- define-properties "^1.1.2"
- function-bind "^1.1.1"
- has-symbols "^1.0.0"
- object-keys "^1.0.11"
+normalize-path@^3.0.0, normalize-path@~3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
+ integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
-object.getownpropertydescriptors@^2.0.3:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
- integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=
+npm-run-path@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
+ integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
dependencies:
- define-properties "^1.1.2"
- es-abstract "^1.5.1"
+ path-key "^3.0.0"
-on-headers@~1.0.1:
+on-headers@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
-once@^1.3.0, once@^1.3.1, once@^1.4.0:
+once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
- integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
-onetime@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
- integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=
+onetime@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
+ integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
dependencies:
- mimic-fn "^1.0.0"
+ mimic-fn "^2.1.0"
-optionator@^0.8.2:
- version "0.8.2"
- resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
- integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=
+optionator@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
+ integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==
dependencies:
- deep-is "~0.1.3"
- fast-levenshtein "~2.0.4"
- levn "~0.3.0"
- prelude-ls "~1.1.2"
- type-check "~0.3.2"
- wordwrap "~1.0.0"
+ deep-is "^0.1.3"
+ fast-levenshtein "^2.0.6"
+ levn "^0.4.1"
+ prelude-ls "^1.2.1"
+ type-check "^0.4.0"
+ word-wrap "^1.2.3"
-os-locale@^3.0.0, os-locale@^3.1.0:
+p-limit@^3.0.2:
version "3.1.0"
- resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
- integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
+ integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
- execa "^1.0.0"
- lcid "^2.0.0"
- mem "^4.0.0"
-
-os-tmpdir@~1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
- integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-p-defer@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c"
- integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=
-
-p-finally@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
- integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
-
-p-is-promise@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
- integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
+ yocto-queue "^0.1.0"
-p-limit@^2.0.0:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537"
- integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==
- dependencies:
- p-try "^2.0.0"
-
-p-locate@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
- integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
+p-locate@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
+ integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
dependencies:
- p-limit "^2.0.0"
-
-p-try@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
- integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
+ p-limit "^3.0.2"
parent-module@^1.0.0:
version "1.0.1"
@@ -1234,73 +1063,72 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-path-exists@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
- integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
+path-exists@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
+ integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
- integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
+ integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-is-inside@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
- integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
+ integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==
-path-key@^2.0.0, path-key@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
- integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
+path-key@^3.0.0, path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-to-regexp@2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45"
integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==
-pathval@^1.1.0:
+pathval@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
-prelude-ls@~1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
- integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-
-progress@^2.0.0:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
- integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
-
-pseudomap@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
- integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
+picomatch@^2.0.4, picomatch@^2.2.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
-pump@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
- integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
- dependencies:
- end-of-stream "^1.1.0"
- once "^1.3.1"
+prelude-ls@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
+ integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
punycode@^1.3.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
- integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
+ integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==
punycode@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
- integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f"
+ integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==
+
+queue-microtask@^1.2.2:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
+ integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+
+randombytes@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
+ integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
+ dependencies:
+ safe-buffer "^5.1.0"
range-parser@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
- integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=
+ integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==
rc@^1.0.1, rc@^1.1.6:
version "1.2.8"
@@ -1312,10 +1140,12 @@ rc@^1.0.1, rc@^1.1.6:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
-regexpp@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
- integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
registry-auth-token@3.3.2:
version "3.3.2"
@@ -1328,451 +1158,317 @@ registry-auth-token@3.3.2:
registry-url@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
- integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI=
+ integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==
dependencies:
rc "^1.0.1"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
- integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
-
-require-main-filename@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
- integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
+ integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
-require-main-filename@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
- integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
+require-from-string@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+ integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
-restore-cursor@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
- integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368=
- dependencies:
- onetime "^2.0.0"
- signal-exit "^3.0.2"
+reusify@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
+ integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-rimraf@2.6.3:
- version "2.6.3"
- resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
- integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
+rimraf@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
+ integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
-rollup@^1.21.4:
- version "1.21.4"
- resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.21.4.tgz#00a41a30f90095db890301b226cbe2918e4cf54d"
- integrity sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw==
- dependencies:
- "@types/estree" "0.0.39"
- "@types/node" "^12.7.5"
- acorn "^7.0.0"
+rollup@^3.23.0:
+ version "3.23.0"
+ resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.23.0.tgz#b8d6146dac4bf058ee817f92820988e9b358b564"
+ integrity sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==
+ optionalDependencies:
+ fsevents "~2.3.2"
-run-async@^2.2.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
- integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA=
- dependencies:
- is-promise "^2.1.0"
-
-rxjs@^6.4.0:
- version "6.5.3"
- resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a"
- integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==
+run-parallel@^1.1.9:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
+ integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
- tslib "^1.9.0"
+ queue-microtask "^1.2.2"
safe-buffer@5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
-safe-buffer@^5.0.1:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
- integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
+safe-buffer@^5.0.1, safe-buffer@^5.1.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
-"safer-buffer@>= 2.1.2 < 3":
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
- integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-
-semver@^5.5.0, semver@^5.7.0:
- version "5.7.1"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-
-semver@^6.1.2:
- version "6.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+serialize-javascript@6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
+ integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
+ dependencies:
+ randombytes "^2.1.0"
-serve-handler@6.1.0:
- version "6.1.0"
- resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.0.tgz#f1606dc6ff8f9029a1ee042c11dfe7903a5cb92e"
- integrity sha512-63N075Tn3PsFYcu0NVV7tb367UbiW3gnC+/50ohL4oqOhAG6bmbaWqiRcXQgbzqc0ALBjSAzg7VTfa0Qw4E3hA==
+serve-handler@6.1.5:
+ version "6.1.5"
+ resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.5.tgz#a4a0964f5c55c7e37a02a633232b6f0d6f068375"
+ integrity sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==
dependencies:
bytes "3.0.0"
content-disposition "0.5.2"
fast-url-parser "1.1.3"
mime-types "2.1.18"
- minimatch "3.0.4"
+ minimatch "3.1.2"
path-is-inside "1.0.2"
path-to-regexp "2.2.1"
range-parser "1.2.0"
-serve@^11.1.0:
- version "11.1.0"
- resolved "https://registry.yarnpkg.com/serve/-/serve-11.1.0.tgz#1bfe2f4a08d0130cbf44711cdb7996cb742172e0"
- integrity sha512-+4wpDtOSS+4ZLyDWMxThutA3iOTawX2+yDovOI8cjOUOmemyvNlHyFAsezBlSgbZKTYChI3tzA1Mh0z6XZ62qA==
- dependencies:
- "@zeit/schemas" "2.6.0"
- ajv "6.5.3"
- arg "2.0.0"
- boxen "1.3.0"
- chalk "2.4.1"
- clipboardy "1.2.3"
- compression "1.7.3"
- serve-handler "6.1.0"
- update-check "1.5.2"
-
-set-blocking@^2.0.0:
+serve@^14.2.0:
+ version "14.2.0"
+ resolved "https://registry.yarnpkg.com/serve/-/serve-14.2.0.tgz#3d768e88fa13ad8644f2393599189707176e66b8"
+ integrity sha512-+HOw/XK1bW8tw5iBilBz/mJLWRzM8XM6MPxL4J/dKzdxq1vfdEWSwhaR7/yS8EJp5wzvP92p1qirysJvnEtjXg==
+ dependencies:
+ "@zeit/schemas" "2.29.0"
+ ajv "8.11.0"
+ arg "5.0.2"
+ boxen "7.0.0"
+ chalk "5.0.1"
+ chalk-template "0.4.0"
+ clipboardy "3.0.0"
+ compression "1.7.4"
+ is-port-reachable "4.0.0"
+ serve-handler "6.1.5"
+ update-check "1.5.4"
+
+shebang-command@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
- integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
-
-shebang-command@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
- integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
- shebang-regex "^1.0.0"
+ shebang-regex "^3.0.0"
-shebang-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
- integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
-
-signal-exit@^3.0.0, signal-exit@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
- integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
-
-slice-ansi@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636"
- integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==
- dependencies:
- ansi-styles "^3.2.0"
- astral-regex "^1.0.0"
- is-fullwidth-code-point "^2.0.0"
-
-sprintf-js@~1.0.2:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
- integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
-
-string-width@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
- integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
- dependencies:
- code-point-at "^1.0.0"
- is-fullwidth-code-point "^1.0.0"
- strip-ansi "^3.0.0"
-
-"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
- integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
- dependencies:
- is-fullwidth-code-point "^2.0.0"
- strip-ansi "^4.0.0"
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-string-width@^3.0.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
- integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
- dependencies:
- emoji-regex "^7.0.1"
- is-fullwidth-code-point "^2.0.0"
- strip-ansi "^5.1.0"
+signal-exit@^3.0.3:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
-string.prototype.trimleft@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634"
- integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==
+string-width@^4.1.0, string-width@^4.2.0:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
-string.prototype.trimright@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58"
- integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==
+string-width@^5.0.1, string-width@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
+ integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
dependencies:
- define-properties "^1.1.3"
- function-bind "^1.1.1"
+ eastasianwidth "^0.2.0"
+ emoji-regex "^9.2.2"
+ strip-ansi "^7.0.1"
-strip-ansi@^3.0.0, strip-ansi@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
- integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
- ansi-regex "^2.0.0"
+ ansi-regex "^5.0.1"
-strip-ansi@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
- integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
+strip-ansi@^7.0.1:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
+ integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
dependencies:
- ansi-regex "^3.0.0"
+ ansi-regex "^6.0.1"
-strip-ansi@^5.1.0, strip-ansi@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
- integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
- dependencies:
- ansi-regex "^4.1.0"
+strip-final-newline@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
+ integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
-strip-eof@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
- integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
+strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
+ integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
-strip-json-comments@2.0.1, strip-json-comments@~2.0.1:
+strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
- integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=
-
-strip-json-comments@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7"
- integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==
+ integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
-supports-color@6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a"
- integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==
+supports-color@8.1.1:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
- has-flag "^3.0.0"
+ has-flag "^4.0.0"
-supports-color@^5.3.0:
- version "5.5.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
- integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
- has-flag "^3.0.0"
-
-table@^5.2.3:
- version "5.4.6"
- resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e"
- integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==
- dependencies:
- ajv "^6.10.2"
- lodash "^4.17.14"
- slice-ansi "^2.1.0"
- string-width "^3.0.0"
-
-term-size@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
- integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=
- dependencies:
- execa "^0.7.0"
+ has-flag "^4.0.0"
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
- integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
-
-through@^2.3.6:
- version "2.3.8"
- resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
- integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
+ integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
-tmp@^0.0.33:
- version "0.0.33"
- resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
- integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==
+to-regex-range@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+ integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
- os-tmpdir "~1.0.2"
-
-tslib@^1.9.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
- integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
+ is-number "^7.0.0"
-type-check@~0.3.2:
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
- integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
+type-check@^0.4.0, type-check@~0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
+ integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
dependencies:
- prelude-ls "~1.1.2"
+ prelude-ls "^1.2.1"
type-detect@^4.0.0, type-detect@^4.0.5:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
-update-check@1.5.2:
- version "1.5.2"
- resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.2.tgz#2fe09f725c543440b3d7dabe8971f2d5caaedc28"
- integrity sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==
+type-fest@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
+ integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
+
+type-fest@^2.13.0:
+ version "2.19.0"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
+ integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
+
+update-check@1.5.4:
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.4.tgz#5b508e259558f1ad7dbc8b4b0457d4c9d28c8743"
+ integrity sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==
dependencies:
registry-auth-token "3.3.2"
registry-url "3.1.0"
uri-js@^4.2.2:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
- integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
+ version "4.4.1"
+ resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
+ integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
-v8-compile-cache@^2.0.3:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
- integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
-
vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
- integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
-
-which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
- integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
+ integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
-which@1.3.1, which@^1.2.9:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
- integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
-wide-align@1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
- integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
+widest-line@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2"
+ integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==
dependencies:
- string-width "^1.0.2 || 2"
+ string-width "^5.0.1"
-widest-line@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc"
- integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==
- dependencies:
- string-width "^2.1.1"
+word-wrap@^1.2.3:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f"
+ integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==
-wordwrap@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
- integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
+workerpool@6.2.1:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
+ integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
-wrap-ansi@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"
- integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+wrap-ansi@^8.0.1:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
+ integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
dependencies:
- string-width "^1.0.1"
- strip-ansi "^3.0.1"
+ ansi-styles "^6.1.0"
+ string-width "^5.0.1"
+ strip-ansi "^7.0.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
- integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-
-write@1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3"
- integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==
- dependencies:
- mkdirp "^0.5.1"
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
-"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
- integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
-
-yallist@^2.1.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
- integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
-
-yargs-parser@13.0.0:
- version "13.0.0"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.0.0.tgz#3fc44f3e76a8bdb1cc3602e860108602e5ccde8b"
- integrity sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
+y18n@^5.0.5:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-yargs-parser@^11.1.1:
- version "11.1.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4"
- integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
+yargs-parser@20.2.4:
+ version "20.2.4"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
+ integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
-yargs-parser@^13.0.0:
- version "13.1.1"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
- integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
+yargs-parser@^20.2.2:
+ version "20.2.9"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
+ integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
-yargs-unparser@1.5.0:
- version "1.5.0"
- resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.5.0.tgz#f2bb2a7e83cbc87bb95c8e572828a06c9add6e0d"
- integrity sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==
- dependencies:
- flat "^4.1.0"
- lodash "^4.17.11"
- yargs "^12.0.5"
-
-yargs@13.2.2:
- version "13.2.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993"
- integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==
- dependencies:
- cliui "^4.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- os-locale "^3.1.0"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^3.0.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^13.0.0"
-
-yargs@^12.0.5:
- version "12.0.5"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"
- integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==
- dependencies:
- cliui "^4.0.0"
- decamelize "^1.2.0"
- find-up "^3.0.0"
- get-caller-file "^1.0.1"
- os-locale "^3.0.0"
+yargs-unparser@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
+ integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
+ dependencies:
+ camelcase "^6.0.0"
+ decamelize "^4.0.0"
+ flat "^5.0.2"
+ is-plain-obj "^2.1.0"
+
+yargs@16.2.0:
+ version "16.2.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+ integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+ dependencies:
+ cliui "^7.0.2"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
require-directory "^2.1.1"
- require-main-filename "^1.0.1"
- set-blocking "^2.0.0"
- string-width "^2.0.0"
- which-module "^2.0.0"
- y18n "^3.2.1 || ^4.0.0"
- yargs-parser "^11.1.1"
+ string-width "^4.2.0"
+ y18n "^5.0.5"
+ yargs-parser "^20.2.2"
+
+yocto-queue@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
+ integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
diff --git a/third_party/SPIRV-Tools/utils/check_copyright.py b/third_party/SPIRV-Tools/utils/check_copyright.py
index e3e74bc9d..a849d0467 100755
--- a/third_party/SPIRV-Tools/utils/check_copyright.py
+++ b/third_party/SPIRV-Tools/utils/check_copyright.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# coding=utf-8
# Copyright (c) 2016 Google Inc.
#
diff --git a/third_party/SPIRV-Tools/utils/check_symbol_exports.py b/third_party/SPIRV-Tools/utils/check_symbol_exports.py
index e1ca0b788..e44294fe8 100755
--- a/third_party/SPIRV-Tools/utils/check_symbol_exports.py
+++ b/third_party/SPIRV-Tools/utils/check_symbol_exports.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/third_party/SPIRV-Tools/utils/fixup_fuzz_result.py b/third_party/SPIRV-Tools/utils/fixup_fuzz_result.py
index 9fe54a3cc..5b14a7db9 100755
--- a/third_party/SPIRV-Tools/utils/fixup_fuzz_result.py
+++ b/third_party/SPIRV-Tools/utils/fixup_fuzz_result.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/third_party/SPIRV-Tools/utils/generate_changelog.py b/third_party/SPIRV-Tools/utils/generate_changelog.py
index 54db72828..348bc50a6 100644
--- a/third_party/SPIRV-Tools/utils/generate_changelog.py
+++ b/third_party/SPIRV-Tools/utils/generate_changelog.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2023 Google Inc.
#
diff --git a/third_party/SPIRV-Tools/utils/generate_grammar_tables.py b/third_party/SPIRV-Tools/utils/generate_grammar_tables.py
index 6b7167b86..88534ffed 100755
--- a/third_party/SPIRV-Tools/utils/generate_grammar_tables.py
+++ b/third_party/SPIRV-Tools/utils/generate_grammar_tables.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -540,7 +540,7 @@ def generate_operand_kind_table(enums):
# We have a few operand kinds that require their optional counterpart to
# exist in the operand info table.
- optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat']
+ optional_enums = ['ImageOperands', 'AccessQualifier', 'MemoryAccess', 'PackedVectorFormat', 'CooperativeMatrixOperands', 'RawAccessChainOperands']
optional_enums = [e for e in enums if e[0] in optional_enums]
enums.extend(optional_enums)
diff --git a/third_party/SPIRV-Tools/utils/generate_language_headers.py b/third_party/SPIRV-Tools/utils/generate_language_headers.py
index 83fa99e1f..18a8d5ea0 100755
--- a/third_party/SPIRV-Tools/utils/generate_language_headers.py
+++ b/third_party/SPIRV-Tools/utils/generate_language_headers.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2017 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/third_party/SPIRV-Tools/utils/generate_registry_tables.py b/third_party/SPIRV-Tools/utils/generate_registry_tables.py
index 28152ef3e..69628faad 100755
--- a/third_party/SPIRV-Tools/utils/generate_registry_tables.py
+++ b/third_party/SPIRV-Tools/utils/generate_registry_tables.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,8 +15,9 @@
"""Generates the vendor tool table from the SPIR-V XML registry."""
import errno
+import io
import os.path
-import xml.etree.ElementTree
+from xml.etree.ElementTree import XML, XMLParser, TreeBuilder
def mkdir_p(directory):
@@ -78,8 +79,9 @@ def main():
help='output file for SPIR-V generators table')
args = parser.parse_args()
- with open(args.xml) as xml_in:
- registry = xml.etree.ElementTree.fromstring(xml_in.read())
+ with io.open(args.xml, encoding='utf-8') as xml_in:
+ parser = XMLParser(target=TreeBuilder(), encoding='utf-8')
+ registry = XML(xml_in.read(), parser=parser)
mkdir_p(os.path.dirname(args.generator_output))
with open(args.generator_output, 'w') as f:
diff --git a/third_party/SPIRV-Tools/utils/generate_vim_syntax.py b/third_party/SPIRV-Tools/utils/generate_vim_syntax.py
index da7e99ba7..5c9c6b21a 100755
--- a/third_party/SPIRV-Tools/utils/generate_vim_syntax.py
+++ b/third_party/SPIRV-Tools/utils/generate_vim_syntax.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2016 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/third_party/SPIRV-Tools/utils/roll_deps.sh b/third_party/SPIRV-Tools/utils/roll_deps.sh
index 6289c94e4..d19ee000e 100755
--- a/third_party/SPIRV-Tools/utils/roll_deps.sh
+++ b/third_party/SPIRV-Tools/utils/roll_deps.sh
@@ -29,7 +29,6 @@ function ExitIfIsInterestingError() {
}
-# We are not rolling google test for now. The latest version requires C++14.
dependencies=("external/effcee/"
"external/googletest/"
"external/re2/"
diff --git a/third_party/SPIRV-Tools/utils/update_build_version.py b/third_party/SPIRV-Tools/utils/update_build_version.py
index 0ee5c082a..bb66e18a5 100755
--- a/third_party/SPIRV-Tools/utils/update_build_version.py
+++ b/third_party/SPIRV-Tools/utils/update_build_version.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# Copyright (c) 2016 Google Inc.
#
@@ -59,14 +59,10 @@ def mkdir_p(directory):
else:
raise
-def command_output(cmd, directory, may_fail=False):
+def command_output(cmd, directory):
"""Runs a command in a directory and returns its standard output stream.
- Captures the standard error stream.
-
- Raises a RuntimeError if the command fails to launch or otherwise fails. If
- `may_fail` is true, suppresses the log message when running the command
- succeeds but returns a non-zero error code.
+ Returns (False, None) if the command fails to launch or otherwise fails.
"""
try:
# Set shell=True on Windows so that Chromium's git.bat can be found when
@@ -76,11 +72,10 @@ def command_output(cmd, directory, may_fail=False):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=os.name == 'nt')
- (stdout, stderr) = p.communicate()
- if p.returncode != 0 and not may_fail:
- logging.error('Failed to run "{}" in "{}": {}'.format(cmd, directory, stderr.decode()))
+ (stdout, _) = p.communicate()
+ if p.returncode != 0:
+ return False, None
except Exception as e:
- logging.error('Failed to run "{}" in "{}": {}'.format(cmd, directory, str(e)))
return False, None
return p.returncode == 0, stdout
@@ -113,26 +108,30 @@ def describe(repo_path):
Runs 'git describe', or alternately 'git rev-parse HEAD', in directory. If
successful, returns the output; otherwise returns 'unknown hash, <date>'."""
- success, output = command_output(['git', 'describe'], repo_path, may_fail=True)
- if not success:
- output = command_output(['git', 'rev-parse', 'HEAD'], repo_path)
-
+ # if we're in a git repository, attempt to extract version info
+ success, output = command_output(["git", "rev-parse", "--show-toplevel"], repo_path)
if success:
- # decode() is needed here for Python3 compatibility. In Python2,
- # str and bytes are the same type, but not in Python3.
- # Popen.communicate() returns a bytes instance, which needs to be
- # decoded into text data first in Python3. And this decode() won't
- # hurt Python2.
- return output.rstrip().decode()
+ success, output = command_output(["git", "describe", "--tags", "--match=v*", "--long"], repo_path)
+ if not success:
+ success, output = command_output(["git", "rev-parse", "HEAD"], repo_path)
+
+ if success:
+ # decode() is needed here for Python3 compatibility. In Python2,
+ # str and bytes are the same type, but not in Python3.
+ # Popen.communicate() returns a bytes instance, which needs to be
+ # decoded into text data first in Python3. And this decode() won't
+ # hurt Python2.
+ return output.rstrip().decode()
# This is the fallback case where git gives us no information,
- # e.g. because the source tree might not be in a git tree.
+ # e.g. because the source tree might not be in a git tree or
+ # git is not available on the system.
# In this case, usually use a timestamp. However, to ensure
# reproducible builds, allow the builder to override the wall
# clock time with environment variable SOURCE_DATE_EPOCH
# containing a (presumably) fixed timestamp.
timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
- iso_date = datetime.datetime.utcfromtimestamp(timestamp).isoformat()
+ iso_date = datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc).isoformat()
return "unknown hash, {}".format(iso_date)
def main():
diff --git a/third_party/llvm-16.0/configs/linux/include/llvm/Config/config.h b/third_party/llvm-16.0/configs/linux/include/llvm/Config/config.h
index 8788e3c6e..5e169c050 100644
--- a/third_party/llvm-16.0/configs/linux/include/llvm/Config/config.h
+++ b/third_party/llvm-16.0/configs/linux/include/llvm/Config/config.h
@@ -222,7 +222,7 @@
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <valgrind/valgrind.h> header file. */
-#define HAVE_VALGRIND_VALGRIND_H 1
+/* #undef HAVE_VALGRIND_VALGRIND_H */
/* Have host's _alloca */
/* #undef HAVE__ALLOCA */
diff --git a/third_party/update-spirvtools.sh b/third_party/update-spirvtools.sh
index 0cd19c082..ca6432b8a 100755
--- a/third_party/update-spirvtools.sh
+++ b/third_party/update-spirvtools.sh
@@ -18,6 +18,8 @@ if [[ $GIT_RESULT == *"CONFLICT"* ]]; then
# CONFLICT is very likely due to Android.mk being deleted in our third_party.
# Delete it, and try to continue.
git rm ${THIRD_PARTY_DIR}/SPIRV-Tools/Android.mk
+ git rm ${THIRD_PARTY_DIR}/SPIRV-Tools/android_test/Android.mk
+ git rm ${THIRD_PARTY_DIR}/SPIRV-Tools/android_test/jni/Application.mk
git -c core.editor=true merge --continue # '-c core.editor=true' prevents the editor from showing
if [ $? -ne 0 ]; then
echo "Could not automatically resolve conflicts."