summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Julian Sikorski <belegdol+github@gmail.com>2021-10-02 18:21:12 +0200
committer GitHub <noreply@github.com>2021-10-02 12:21:12 -0400
commit0eeb918991d9d9d5acac6eab82fb6b73b9ff71b4 (patch)
treeb6cf6f1b41da8b7650252e8275e69573811692aa
parent1d61695dabe1aebe22a5db080ec7cc3dac680906 (diff)
Update bgfx, bx and bimg to latest upstream (fixes issue #8057) (#8645)
-rw-r--r--3rdparty/bgfx/.travis.yml36
-rw-r--r--3rdparty/bgfx/3rdparty/cgltf/cgltf.h135
-rw-r--r--3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h43
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp1161
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui.h129
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp81
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp36
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h280
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp9
-rw-r--r--3rdparty/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp251
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/CHANGES.md11
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h3
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp34
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp1
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp17
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp6
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/build_info.h2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp6
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseables.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/Include/Common.h4
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/Include/Types.h10
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/Include/intermediate.h2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp62
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp54
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp13
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp12
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h4
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp38
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h29
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp7
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp2
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.m410
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y10
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp378
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp1
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp31
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.h16
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp5
-rw-r--r--3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_beta.h95
-rw-r--r--3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h135
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp60
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp197
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/SPIRV-Headers.pc.in9
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h171
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVulkanDebugInfo100.h171
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json (renamed from 3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json)0
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json101
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.cs4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp116
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.lua4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.py4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spv.d4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticShaderDebugInfo100.h165
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticVulkanDebugInfo100.h165
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc5
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc8
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc1
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/generators.inc2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc (renamed from 3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vulkan.debuginfo.100.insts.inc)2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc17
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h7
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp28
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/binary.cpp3
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/common_debug_info.h4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp15
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json637
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp245
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.h163
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp169
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/lint/linter.cpp21
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lints.h34
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/operand.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp405
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h73
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/block_merge_util.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/compact_ids_pass.cpp5
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.h3
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp437
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h207
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.cpp91
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.h148
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp305
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.h16
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/def_use_manager.cpp21
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.cpp8
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.h8
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp225
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/if_conversion.cpp1
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp13
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp60
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.h12
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.cpp80
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.h45
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp10
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp48
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp15
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp15
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp15
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/loop_unroller.cpp6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.cpp37
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.h2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp62
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/pass.cpp4
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/passes.h1
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp5
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.h8
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reflect.h2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp18
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp18
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h3
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.cpp32
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.h7
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.cpp5
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.h2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/util/hex_float.h16
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/construct.cpp3
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/function.cpp3
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp5
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_atomics.cpp2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp11
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_cfg.cpp12
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp38
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp1074
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp20
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp79
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp6
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp11
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_type.cpp2
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp122
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.h37
-rw-r--r--3rdparty/bgfx/CONTRIBUTING.md5
-rw-r--r--3rdparty/bgfx/README.md22
-rw-r--r--3rdparty/bgfx/bindings/bf/bgfx.bf5
-rw-r--r--3rdparty/bgfx/bindings/cs/bgfx.cs5
-rw-r--r--3rdparty/bgfx/bindings/d/types.d1
-rw-r--r--3rdparty/bgfx/examples/18-ibl/ibl.cpp4
-rw-r--r--3rdparty/bgfx/examples/28-wireframe/wireframe.cpp8
-rw-r--r--3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp6
-rw-r--r--3rdparty/bgfx/examples/36-sky/sky.cpp24
-rw-r--r--3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp4
-rw-r--r--3rdparty/bgfx/examples/39-assao/cs_assao_generate_importance_map.sc2
-rw-r--r--3rdparty/bgfx/examples/39-assao/cs_assao_generate_q.sh8
-rw-r--r--3rdparty/bgfx/examples/39-assao/cs_assao_smart_blur.sc8
-rw-r--r--3rdparty/bgfx/examples/common/bgfx_utils.cpp1
-rw-r--r--3rdparty/bgfx/examples/common/bounds.cpp204
-rw-r--r--3rdparty/bgfx/examples/common/bounds.h36
-rw-r--r--3rdparty/bgfx/examples/common/camera.cpp6
-rw-r--r--3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp44
-rw-r--r--3rdparty/bgfx/examples/common/entry/dialog_darwin.mm153
-rw-r--r--3rdparty/bgfx/examples/common/ps/particle_system.cpp4
-rw-r--r--3rdparty/bgfx/include/bgfx/bgfx.h1
-rw-r--r--3rdparty/bgfx/include/bgfx/c99/bgfx.h21
-rw-r--r--3rdparty/bgfx/include/bgfx/embedded_shader.h132
-rw-r--r--3rdparty/bgfx/scripts/bgfx.idl7
-rw-r--r--3rdparty/bgfx/scripts/bgfx.lua5
-rw-r--r--3rdparty/bgfx/src/amalgamated.cpp1
-rw-r--r--3rdparty/bgfx/src/bgfx.cpp63
-rw-r--r--3rdparty/bgfx/src/bgfx_p.h85
-rw-r--r--3rdparty/bgfx/src/bgfx_shader.sh54
-rw-r--r--3rdparty/bgfx/src/config.h13
-rw-r--r--3rdparty/bgfx/src/dxgi.cpp8
-rw-r--r--3rdparty/bgfx/src/dxgi.h4
-rw-r--r--3rdparty/bgfx/src/renderer_agc.cpp20
-rw-r--r--3rdparty/bgfx/src/renderer_d3d11.cpp47
-rw-r--r--3rdparty/bgfx/src/renderer_d3d12.cpp37
-rw-r--r--3rdparty/bgfx/src/renderer_gl.cpp61
-rw-r--r--3rdparty/bgfx/src/renderer_gnm.cpp13
-rw-r--r--3rdparty/bgfx/src/renderer_mtl.mm36
-rw-r--r--3rdparty/bgfx/src/renderer_nvn.cpp9
-rw-r--r--3rdparty/bgfx/src/renderer_vk.cpp74
-rw-r--r--3rdparty/bgfx/src/renderer_vk.h22
-rw-r--r--3rdparty/bgfx/src/vertexlayout.cpp1
-rw-r--r--3rdparty/bgfx/tools/geometryc/geometryc.cpp30
-rw-r--r--3rdparty/bgfx/tools/geometryv/geometryv.cpp6
-rw-r--r--3rdparty/bgfx/tools/shaderc/shaderc.cpp9
-rw-r--r--3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp6
-rw-r--r--3rdparty/bimg/.travis.yml32
-rw-r--r--3rdparty/bimg/README.md1
-rw-r--r--3rdparty/bimg/src/image_cubemap_filter.cpp4
-rw-r--r--3rdparty/bx/.travis.yml29
-rw-r--r--3rdparty/bx/README.md1
-rw-r--r--3rdparty/bx/include/bx/inline/math.inl209
-rw-r--r--3rdparty/bx/include/bx/inline/string.inl16
-rw-r--r--3rdparty/bx/include/bx/math.h94
-rw-r--r--3rdparty/bx/include/bx/platform.h9
-rw-r--r--3rdparty/bx/include/bx/string.h6
-rw-r--r--3rdparty/bx/tests/math_test.cpp2
-rw-r--r--3rdparty/bx/tests/string_test.cpp14
-rw-r--r--scripts/src/3rdparty.lua1
205 files changed, 7281 insertions, 4020 deletions
diff --git a/3rdparty/bgfx/.travis.yml b/3rdparty/bgfx/.travis.yml
deleted file mode 100644
index 0d56a6b9be5..00000000000
--- a/3rdparty/bgfx/.travis.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-language: cpp
-matrix:
- include:
- - compiler: gcc
- os: linux
- - compiler: clang
- os: osx
-
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - gcc-8
- - g++-8
- - clang
- - libgl1-mesa-dev
- - x11proto-core-dev
- - libx11-dev
-
-before_script:
- - git clone --depth 1 https://github.com/bkaradzic/bx ../bx
- - git clone --depth 1 https://github.com/bkaradzic/bimg ../bimg
-
-script:
- - if [ "$TRAVIS_OS_NAME" == "linux" ]; then make build CXX="g++-8" CC="gcc-8"; fi
- - if [ "$TRAVIS_OS_NAME" == "osx" ]; then make osx-x64-debug; fi
-
-branches:
- only:
- - master
-
-notifications:
- email: false
-
-osx_image: xcode11
diff --git a/3rdparty/bgfx/3rdparty/cgltf/cgltf.h b/3rdparty/bgfx/3rdparty/cgltf/cgltf.h
index 300a1466fe2..5650038019d 100644
--- a/3rdparty/bgfx/3rdparty/cgltf/cgltf.h
+++ b/3rdparty/bgfx/3rdparty/cgltf/cgltf.h
@@ -1,7 +1,7 @@
/**
* cgltf - a single-file glTF 2.0 parser written in C99.
*
- * Version: 1.10
+ * Version: 1.11
*
* Website: https://github.com/jkuhlmann/cgltf
*
@@ -234,6 +234,12 @@ typedef enum cgltf_light_type {
cgltf_light_type_spot,
} cgltf_light_type;
+typedef enum cgltf_data_free_method {
+ cgltf_data_free_method_none,
+ cgltf_data_free_method_file_release,
+ cgltf_data_free_method_memory_free,
+} cgltf_data_free_method;
+
typedef struct cgltf_extras {
cgltf_size start_offset;
cgltf_size end_offset;
@@ -250,6 +256,7 @@ typedef struct cgltf_buffer
cgltf_size size;
char* uri;
void* data; /* loaded by cgltf_load_buffers */
+ cgltf_data_free_method data_free_method;
cgltf_extras extras;
cgltf_size extensions_count;
cgltf_extension* extensions;
@@ -384,6 +391,7 @@ typedef struct cgltf_texture_transform
cgltf_float offset[2];
cgltf_float rotation;
cgltf_float scale[2];
+ cgltf_bool has_texcoord;
cgltf_int texcoord;
} cgltf_texture_transform;
@@ -771,6 +779,7 @@ cgltf_result cgltf_load_buffers(
cgltf_result cgltf_load_buffer_base64(const cgltf_options* options, cgltf_size size, const char* base64, void** out_data);
+void cgltf_decode_string(char* string);
void cgltf_decode_uri(char* uri);
cgltf_result cgltf_validate(cgltf_data* data);
@@ -816,7 +825,7 @@ cgltf_result cgltf_copy_extras_json(const cgltf_data* data, const cgltf_extras*
#include <limits.h> /* For UINT_MAX etc */
#include <float.h> /* For FLT_MAX */
-#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF)
+#if !defined(CGLTF_MALLOC) || !defined(CGLTF_FREE) || !defined(CGLTF_ATOI) || !defined(CGLTF_ATOF) || !defined(CGLTF_ATOLL)
#include <stdlib.h> /* For malloc, free, atoi, atof */
#endif
@@ -886,6 +895,9 @@ static const uint32_t GlbMagicBinChunk = 0x004E4942;
#ifndef CGLTF_ATOF
#define CGLTF_ATOF(str) atof(str)
#endif
+#ifndef CGLTF_ATOLL
+#define CGLTF_ATOLL(str) atoll(str)
+#endif
#ifndef CGLTF_VALIDATE_ENABLE_ASSERTS
#define CGLTF_VALIDATE_ENABLE_ASSERTS 0
#endif
@@ -935,7 +947,12 @@ static cgltf_result cgltf_default_file_read(const struct cgltf_memory_options* m
{
fseek(file, 0, SEEK_END);
+#ifdef _WIN32
+ __int64 length = _ftelli64(file);
+#else
long length = ftell(file);
+#endif
+
if (length < 0)
{
fclose(file);
@@ -1123,8 +1140,8 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
return cgltf_result_invalid_options;
}
- void (*memory_free)(void*, void*) = options->memory.free ? options->memory.free : &cgltf_default_free;
cgltf_result (*file_read)(const struct cgltf_memory_options*, const struct cgltf_file_options*, const char*, cgltf_size*, void**) = options->file.read ? options->file.read : &cgltf_default_file_read;
+ void (*file_release)(const struct cgltf_memory_options*, const struct cgltf_file_options*, void* data) = options->file.release ? options->file.release : cgltf_default_file_release;
void* file_data = NULL;
cgltf_size file_size = 0;
@@ -1138,7 +1155,7 @@ cgltf_result cgltf_parse_file(const cgltf_options* options, const char* path, cg
if (result != cgltf_result_success)
{
- memory_free(options->memory.user_data, file_data);
+ file_release(&options->memory, &options->file, file_data);
return result;
}
@@ -1249,6 +1266,72 @@ static int cgltf_unhex(char ch)
-1;
}
+void cgltf_decode_string(char* string)
+{
+ char* read = strchr(string, '\\');
+ if (read == NULL)
+ {
+ return;
+ }
+ char* write = string;
+ char* last = string;
+
+ while (read)
+ {
+ // Copy characters since last escaped sequence
+ cgltf_size written = read - last;
+ strncpy(write, last, written);
+ write += written;
+
+ // jsmn already checked that all escape sequences are valid
+ ++read;
+ switch (*read++)
+ {
+ case '\"': *write++ = '\"'; break;
+ case '/': *write++ = '/'; break;
+ case '\\': *write++ = '\\'; break;
+ case 'b': *write++ = '\b'; break;
+ case 'f': *write++ = '\f'; break;
+ case 'r': *write++ = '\r'; break;
+ case 'n': *write++ = '\n'; break;
+ case 't': *write++ = '\t'; break;
+ case 'u':
+ {
+ // UCS-2 codepoint \uXXXX to UTF-8
+ int character = 0;
+ for (cgltf_size i = 0; i < 4; ++i)
+ {
+ character = (character << 4) + cgltf_unhex(*read++);
+ }
+
+ if (character <= 0x7F)
+ {
+ *write++ = character & 0xFF;
+ }
+ else if (character <= 0x7FF)
+ {
+ *write++ = 0xC0 | ((character >> 6) & 0xFF);
+ *write++ = 0x80 | (character & 0x3F);
+ }
+ else
+ {
+ *write++ = 0xE0 | ((character >> 12) & 0xFF);
+ *write++ = 0x80 | ((character >> 6) & 0x3F);
+ *write++ = 0x80 | (character & 0x3F);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ last = read;
+ read = strchr(read, '\\');
+ }
+
+ strcpy(write, last);
+}
+
void cgltf_decode_uri(char* uri)
{
char* write = uri;
@@ -1294,6 +1377,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data,
}
data->buffers[0].data = (void*)data->bin;
+ data->buffers[0].data_free_method = cgltf_data_free_method_none;
}
for (cgltf_size i = 0; i < data->buffers_count; ++i)
@@ -1317,6 +1401,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data,
if (comma && comma - uri >= 7 && strncmp(comma - 7, ";base64", 7) == 0)
{
cgltf_result res = cgltf_load_buffer_base64(options, data->buffers[i].size, comma + 1, &data->buffers[i].data);
+ data->buffers[i].data_free_method = cgltf_data_free_method_memory_free;
if (res != cgltf_result_success)
{
@@ -1331,6 +1416,7 @@ cgltf_result cgltf_load_buffers(const cgltf_options* options, cgltf_data* data,
else if (strstr(uri, "://") == NULL && gltf_path)
{
cgltf_result res = cgltf_load_buffer_file(options, data->buffers[i].size, uri, gltf_path, &data->buffers[i].data);
+ data->buffers[i].data_free_method = cgltf_data_free_method_file_release;
if (res != cgltf_result_success)
{
@@ -1658,10 +1744,15 @@ void cgltf_free(cgltf_data* data)
{
data->memory.free(data->memory.user_data, data->buffers[i].name);
- if (data->buffers[i].data != data->bin)
+ if (data->buffers[i].data_free_method == cgltf_data_free_method_file_release)
{
file_release(&data->memory, &data->file, data->buffers[i].data);
}
+ else if (data->buffers[i].data_free_method == cgltf_data_free_method_memory_free)
+ {
+ data->memory.free(data->memory.user_data, data->buffers[i].data);
+ }
+
data->memory.free(data->memory.user_data, data->buffers[i].uri);
cgltf_free_extensions(data, data->buffers[i].extensions, data->buffers[i].extensions_count);
@@ -2262,6 +2353,7 @@ cgltf_size cgltf_accessor_read_index(const cgltf_accessor* accessor, cgltf_size
#define CGLTF_ERROR_LEGACY -3
#define CGLTF_CHECK_TOKTYPE(tok_, type_) if ((tok_).type != (type_)) { return CGLTF_ERROR_JSON; }
+#define CGLTF_CHECK_TOKTYPE_RETTYPE(tok_, type_, ret_) if ((tok_).type != (type_)) { return (ret_)CGLTF_ERROR_JSON; }
#define CGLTF_CHECK_KEY(tok_) if ((tok_).type != JSMN_STRING || (tok_).size == 0) { return CGLTF_ERROR_JSON; } /* checking size for 0 verifies that a value follows the key */
#define CGLTF_PTRINDEX(type, idx) (type*)((cgltf_size)idx + 1)
@@ -2286,6 +2378,16 @@ static int cgltf_json_to_int(jsmntok_t const* tok, const uint8_t* json_chunk)
return CGLTF_ATOI(tmp);
}
+static cgltf_size cgltf_json_to_size(jsmntok_t const* tok, const uint8_t* json_chunk)
+{
+ CGLTF_CHECK_TOKTYPE_RETTYPE(*tok, JSMN_PRIMITIVE, cgltf_size);
+ char tmp[128];
+ int size = (cgltf_size)(tok->end - tok->start) < sizeof(tmp) ? tok->end - tok->start : (int)(sizeof(tmp) - 1);
+ strncpy(tmp, (const char*)json_chunk + tok->start, size);
+ tmp[size] = 0;
+ return (cgltf_size)CGLTF_ATOLL(tmp);
+}
+
static cgltf_float cgltf_json_to_float(jsmntok_t const* tok, const uint8_t* json_chunk)
{
CGLTF_CHECK_TOKTYPE(*tok, JSMN_PRIMITIVE);
@@ -3027,7 +3129,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
{
++i;
- out_sparse->indices_byte_offset = cgltf_json_to_int(tokens + i, json_chunk);
+ out_sparse->indices_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
@@ -3076,7 +3178,7 @@ static int cgltf_parse_json_accessor_sparse(cgltf_options* options, jsmntok_t co
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
{
++i;
- out_sparse->values_byte_offset = cgltf_json_to_int(tokens + i, json_chunk);
+ out_sparse->values_byte_offset = cgltf_json_to_size(tokens + i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens + i, json_chunk, "extras") == 0)
@@ -3145,7 +3247,7 @@ static int cgltf_parse_json_accessor(cgltf_options* options, jsmntok_t const* to
{
++i;
out_accessor->offset =
- cgltf_json_to_int(tokens+i, json_chunk);
+ cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "componentType") == 0)
@@ -3271,6 +3373,7 @@ static int cgltf_parse_json_texture_transform(jsmntok_t const* tokens, int i, co
else if (cgltf_json_strcmp(tokens + i, json_chunk, "texCoord") == 0)
{
++i;
+ out_texture_transform->has_texcoord = 1;
out_texture_transform->texcoord = cgltf_json_to_int(tokens + i, json_chunk);
++i;
}
@@ -4250,19 +4353,19 @@ static int cgltf_parse_json_meshopt_compression(cgltf_options* options, jsmntok_
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteOffset") == 0)
{
++i;
- out_meshopt_compression->offset = cgltf_json_to_int(tokens+i, json_chunk);
+ out_meshopt_compression->offset = cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
{
++i;
- out_meshopt_compression->size = cgltf_json_to_int(tokens+i, json_chunk);
+ out_meshopt_compression->size = cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0)
{
++i;
- out_meshopt_compression->stride = cgltf_json_to_int(tokens+i, json_chunk);
+ out_meshopt_compression->stride = cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "count") == 0)
@@ -4348,21 +4451,21 @@ static int cgltf_parse_json_buffer_view(cgltf_options* options, jsmntok_t const*
{
++i;
out_buffer_view->offset =
- cgltf_json_to_int(tokens+i, json_chunk);
+ cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteLength") == 0)
{
++i;
out_buffer_view->size =
- cgltf_json_to_int(tokens+i, json_chunk);
+ cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "byteStride") == 0)
{
++i;
out_buffer_view->stride =
- cgltf_json_to_int(tokens+i, json_chunk);
+ cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "target") == 0)
@@ -4480,7 +4583,7 @@ static int cgltf_parse_json_buffer(cgltf_options* options, jsmntok_t const* toke
{
++i;
out_buffer->size =
- cgltf_json_to_int(tokens+i, json_chunk);
+ cgltf_json_to_size(tokens+i, json_chunk);
++i;
}
else if (cgltf_json_strcmp(tokens+i, json_chunk, "uri") == 0)
@@ -6376,7 +6479,7 @@ static void jsmn_init(jsmn_parser *parser) {
/* cgltf is distributed under MIT license:
*
- * Copyright (c) 2018 Johannes Kuhlmann
+ * Copyright (c) 2018-2021 Johannes Kuhlmann
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h b/3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h
index 50a9d8064af..8b96eb2b664 100644
--- a/3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h
+++ b/3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h
@@ -1,7 +1,7 @@
/**
* cgltf_write - a single-file glTF 2.0 writer written in C99.
*
- * Version: 1.10
+ * Version: 1.11
*
* Website: https://github.com/jkuhlmann/cgltf
*
@@ -64,6 +64,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
#ifdef CGLTF_WRITE_IMPLEMENTATION
+#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
@@ -109,6 +110,7 @@ typedef struct {
#endif
#define CGLTF_SPRINTF(...) { \
+ assert(context->cursor || (!context->cursor && context->remaining == 0)); \
context->tmp = snprintf ( context->cursor, context->remaining, __VA_ARGS__ ); \
context->chars_written += context->tmp; \
if (context->cursor) { \
@@ -117,6 +119,7 @@ typedef struct {
} }
#define CGLTF_SNPRINTF(length, ...) { \
+ assert(context->cursor || (!context->cursor && context->remaining == 0)); \
context->tmp = snprintf ( context->cursor, CGLTF_MIN(length + 1, context->remaining), __VA_ARGS__ ); \
context->chars_written += length; \
if (context->cursor) { \
@@ -230,6 +233,16 @@ static void cgltf_write_intprop(cgltf_write_context* context, const char* label,
}
}
+static void cgltf_write_sizeprop(cgltf_write_context* context, const char* label, cgltf_size val, cgltf_size def)
+{
+ if (val != def)
+ {
+ cgltf_write_indent(context);
+ CGLTF_SPRINTF("\"%s\": %zu", label, val);
+ context->needs_comma = 1;
+ }
+}
+
static void cgltf_write_floatprop(cgltf_write_context* context, const char* label, float val, float def)
{
if (val != def)
@@ -378,7 +391,10 @@ static void cgltf_write_texture_transform(cgltf_write_context* context, const cg
{
cgltf_write_floatarrayprop(context, "scale", transform->scale, 2);
}
- cgltf_write_intprop(context, "texCoord", transform->texcoord, 0);
+ if (transform->has_texcoord)
+ {
+ cgltf_write_intprop(context, "texCoord", transform->texcoord, -1);
+ }
cgltf_write_line(context, "}");
cgltf_write_line(context, "}");
}
@@ -501,9 +517,9 @@ static void cgltf_write_buffer_view(cgltf_write_context* context, const cgltf_bu
cgltf_write_line(context, "{");
cgltf_write_strprop(context, "name", view->name);
CGLTF_WRITE_IDXPROP("buffer", view->buffer, context->data->buffers);
- cgltf_write_intprop(context, "byteLength", (int)view->size, -1);
- cgltf_write_intprop(context, "byteOffset", (int)view->offset, 0);
- cgltf_write_intprop(context, "byteStride", (int)view->stride, 0);
+ cgltf_write_sizeprop(context, "byteLength", view->size, (cgltf_size)-1);
+ cgltf_write_sizeprop(context, "byteOffset", view->offset, 0);
+ cgltf_write_sizeprop(context, "byteStride", view->stride, 0);
// NOTE: We skip writing "target" because the spec says its usage can be inferred.
cgltf_write_extras(context, &view->extras);
cgltf_write_line(context, "}");
@@ -515,7 +531,7 @@ static void cgltf_write_buffer(cgltf_write_context* context, const cgltf_buffer*
cgltf_write_line(context, "{");
cgltf_write_strprop(context, "name", buffer->name);
cgltf_write_strprop(context, "uri", buffer->uri);
- cgltf_write_intprop(context, "byteLength", (int)buffer->size, -1);
+ cgltf_write_sizeprop(context, "byteLength", buffer->size, (cgltf_size)-1);
cgltf_write_extras(context, &buffer->extras);
cgltf_write_line(context, "}");
}
@@ -524,7 +540,10 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
{
cgltf_write_line(context, "{");
cgltf_write_strprop(context, "name", material->name);
- cgltf_write_floatprop(context, "alphaCutoff", material->alpha_cutoff, 0.5f);
+ if (material->alpha_mode == cgltf_alpha_mode_mask)
+ {
+ cgltf_write_floatprop(context, "alphaCutoff", material->alpha_cutoff, 0.5f);
+ }
cgltf_write_boolprop_optional(context, "doubleSided", material->double_sided, false);
// cgltf_write_boolprop_optional(context, "unlit", material->unlit, false);
@@ -663,7 +682,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater
CGLTF_WRITE_TEXTURE_INFO("specularGlossinessTexture", params->specular_glossiness_texture);
if (cgltf_check_floatarray(params->diffuse_factor, 4, 1.0f))
{
- cgltf_write_floatarrayprop(context, "dffuseFactor", params->diffuse_factor, 4);
+ cgltf_write_floatarrayprop(context, "diffuseFactor", params->diffuse_factor, 4);
}
if (cgltf_check_floatarray(params->specular_factor, 3, 1.0f))
{
@@ -907,7 +926,7 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces
cgltf_write_strprop(context, "type", cgltf_str_from_type(accessor->type));
cgltf_size dim = cgltf_dim_from_type(accessor->type);
cgltf_write_boolprop_optional(context, "normalized", accessor->normalized, false);
- cgltf_write_intprop(context, "byteOffset", (int)accessor->offset, 0);
+ cgltf_write_sizeprop(context, "byteOffset", (int)accessor->offset, 0);
cgltf_write_intprop(context, "count", (int)accessor->count, -1);
if (accessor->has_min)
{
@@ -922,13 +941,13 @@ static void cgltf_write_accessor(cgltf_write_context* context, const cgltf_acces
cgltf_write_line(context, "\"sparse\": {");
cgltf_write_intprop(context, "count", (int)accessor->sparse.count, 0);
cgltf_write_line(context, "\"indices\": {");
- cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.indices_byte_offset, 0);
+ cgltf_write_sizeprop(context, "byteOffset", (int)accessor->sparse.indices_byte_offset, 0);
CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.indices_buffer_view, context->data->buffer_views);
cgltf_write_intprop(context, "componentType", cgltf_int_from_component_type(accessor->sparse.indices_component_type), 0);
cgltf_write_extras(context, &accessor->sparse.indices_extras);
cgltf_write_line(context, "}");
cgltf_write_line(context, "\"values\": {");
- cgltf_write_intprop(context, "byteOffset", (int)accessor->sparse.values_byte_offset, 0);
+ cgltf_write_sizeprop(context, "byteOffset", (int)accessor->sparse.values_byte_offset, 0);
CGLTF_WRITE_IDXPROP("bufferView", accessor->sparse.values_buffer_view, context->data->buffer_views);
cgltf_write_extras(context, &accessor->sparse.values_extras);
cgltf_write_line(context, "}");
@@ -1292,7 +1311,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si
/* cgltf is distributed under MIT license:
*
- * Copyright (c) 2019 Philip Rideout
+ * Copyright (c) 2019-2021 Philip Rideout
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp
index ef011070a79..4d8b3673cde 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (main code and documentation)
// Help:
@@ -11,11 +11,14 @@
// - FAQ http://dearimgui.org/faq
// - Homepage & latest https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases
-// - Gallery https://github.com/ocornut/imgui/issues/3793 (please post your screenshots/video there!)
+// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Issues & support https://github.com/ocornut/imgui/issues
-// - Discussions https://github.com/ocornut/imgui/discussions
+
+// Getting Started?
+// - For first-time users having issues compiling/linking/running or issues loading fonts:
+// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
// See LICENSE.txt for copyright and licensing details (standard MIT License).
@@ -376,6 +379,7 @@ CODE
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
+ - 2021/08/23 (1.85) - removed GetWindowContentRegionWidth() function. keep inline redirection helper. can use 'GetWindowContentRegionMax().x - GetWindowContentRegionMin().x' instead.
- 2021/07/26 (1.84) - commented out redirecting functions/enums names that were marked obsolete in 1.67 and 1.69 (March 2019):
- ImGui::GetOverlayDrawList() -> use ImGui::GetForegroundDrawList()
- ImFont::GlyphRangesBuilder -> use ImFontGlyphRangesBuilder
@@ -908,14 +912,14 @@ namespace ImGui
static void NavUpdate();
static void NavUpdateWindowing();
static void NavUpdateWindowingOverlay();
-static void NavUpdateMoveResult();
-static void NavUpdateInitResult();
+static void NavUpdateCancelRequest();
+static void NavUpdateCreateMoveRequest();
static float NavUpdatePageUpPageDown();
static inline void NavUpdateAnyRequestFlag();
static void NavEndFrame();
-static bool NavScoreItem(ImGuiNavItemData* result, ImRect cand);
-static void NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel);
-static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
+static bool NavScoreItem(ImGuiNavItemData* result);
+static void NavApplyItemToResult(ImGuiNavItemData* result);
+static void NavProcessItem();
static ImVec2 NavCalcPreferredRefPos();
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
@@ -990,7 +994,8 @@ static void* GImAllocatorUserData = NULL;
ImGuiStyle::ImGuiStyle()
{
- Alpha = 1.0f; // Global alpha applies to everything in ImGui
+ Alpha = 1.0f; // Global alpha applies to everything in Dear ImGui.
+ DisabledAlpha = 0.60f; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
WindowPadding = ImVec2(8,8); // Padding within a window
WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
@@ -1182,6 +1187,24 @@ void ImGuiIO::ClearInputCharacters()
InputQueueCharacters.resize(0);
}
+void ImGuiIO::ClearInputKeys()
+{
+ memset(KeysDown, 0, sizeof(KeysDown));
+ for (int n = 0; n < IM_ARRAYSIZE(KeysDownDuration); n++)
+ KeysDownDuration[n] = KeysDownDurationPrev[n] = -1.0f;
+ KeyCtrl = KeyShift = KeyAlt = KeySuper = false;
+ KeyMods = KeyModsPrev = ImGuiKeyModFlags_None;
+ for (int n = 0; n < IM_ARRAYSIZE(NavInputsDownDuration); n++)
+ NavInputsDownDuration[n] = NavInputsDownDurationPrev[n] = -1.0f;
+}
+
+void ImGuiIO::AddFocusEvent(bool focused)
+{
+ // We intentionally overwrite this and process in NewFrame(), in order to give a chance
+ // to multi-viewports backends to queue AddFocusEvent(false),AddFocusEvent(true) in same frame.
+ AppFocusLost = !focused;
+}
+
//-----------------------------------------------------------------------------
// [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
//-----------------------------------------------------------------------------
@@ -2238,21 +2261,21 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items
return;
}
- // We create the union of the ClipRect and the NavScoringRect which at worst should be 1 page away from ClipRect
+ // We create the union of the ClipRect and the scoring rect which at worst should be 1 page away from ClipRect
ImRect unclipped_rect = window->ClipRect;
- if (g.NavMoveRequest)
+ if (g.NavMoveScoringItems)
unclipped_rect.Add(g.NavScoringRect);
if (g.NavJustMovedToId && window->NavLastIds[0] == g.NavJustMovedToId)
- unclipped_rect.Add(ImRect(window->Pos + window->NavRectRel[0].Min, window->Pos + window->NavRectRel[0].Max));
+ unclipped_rect.Add(ImRect(window->Pos + window->NavRectRel[0].Min, window->Pos + window->NavRectRel[0].Max)); // Could store and use NavJustMovedToRectRel
const ImVec2 pos = window->DC.CursorPos;
int start = (int)((unclipped_rect.Min.y - pos.y) / items_height);
int end = (int)((unclipped_rect.Max.y - pos.y) / items_height);
// When performing a navigation request, ensure we have one item extra in the direction we are moving to
- if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Up)
+ if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Up)
start--;
- if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Down)
+ if (g.NavMoveScoringItems && g.NavMoveClipDir == ImGuiDir_Down)
end++;
start = ImClamp(start, 0, items_count);
@@ -2519,6 +2542,7 @@ struct ImGuiStyleVarInfo
static const ImGuiStyleVarInfo GStyleVarInfo[] =
{
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
+ { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha
{ ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
{ ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
@@ -3086,7 +3110,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
if (id)
{
g.ActiveIdIsAlive = id;
- g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse;
+ g.ActiveIdSource = (g.NavActivateId == id || g.NavActivateInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse;
}
// Clear declaration of inputs claimed by the widget
@@ -3263,20 +3287,21 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return true;
}
-bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged)
+bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (!bb.Overlaps(window->ClipRect))
if (id == 0 || (id != g.ActiveId && id != g.NavId))
- if (clip_even_when_logged || !g.LogEnabled)
+ if (!g.LogEnabled)
return true;
return false;
}
// Called by ItemAdd()
// Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
-void ImGui::ItemFocusable(ImGuiWindow* window, ImGuiID id)
+// [WIP] This will eventually be refactored and moved into NavProcessItem()
+void ImGui::ItemInputable(ImGuiWindow* window, ImGuiID id)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(id != 0 && id == g.LastItemData.ID);
@@ -3310,7 +3335,7 @@ void ImGui::ItemFocusable(ImGuiWindow* window, ImGuiID id)
}
if (is_tab_stop && window->DC.FocusCounterTabStop == g.TabFocusRequestCurrCounterTabStop)
{
- g.NavJustTabbedId = id;
+ g.NavJustTabbedId = id; // FIXME-NAV: aim to eventually set in NavUpdate() once we finish the refactor
g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_FocusedByTabbing;
return;
}
@@ -3663,13 +3688,15 @@ static void ImGui::UpdateMouseInputs()
// Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
if (IsMousePosValid(&g.IO.MousePos))
- g.IO.MousePos = g.LastValidMousePos = ImFloor(g.IO.MousePos);
+ g.IO.MousePos = g.MouseLastValidPos = ImFloor(g.IO.MousePos);
// If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev))
g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev;
else
g.IO.MouseDelta = ImVec2(0.0f, 0.0f);
+
+ // If mouse moved we re-enable mouse hovering in case it was disabled by gamepad/keyboard. In theory should use a >0.0f threshold but would need to reset in everywhere we set this to true.
if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)
g.NavDisableMouseHover = false;
@@ -3851,6 +3878,7 @@ void ImGui::UpdateTabFocus()
void ImGui::UpdateHoveredWindowAndCaptureFlags()
{
ImGuiContext& g = *GImGui;
+ ImGuiIO& io = g.IO;
g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING));
// Find the window hovered by mouse:
@@ -3862,52 +3890,65 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
// Modal windows prevents mouse from hovering behind them.
ImGuiWindow* modal_window = GetTopMostPopupModal();
- if (modal_window && g.HoveredWindow && !IsWindowChildOf(g.HoveredWindow->RootWindow, modal_window))
+ if (modal_window && g.HoveredWindow && !IsWindowChildOf(g.HoveredWindow->RootWindow, modal_window, true))
clear_hovered_windows = true;
// Disabled mouse?
- if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
+ if (io.ConfigFlags & ImGuiConfigFlags_NoMouse)
clear_hovered_windows = true;
- // We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
- int mouse_earliest_button_down = -1;
+ // We track click ownership. When clicked outside of a window the click is owned by the application and
+ // won't report hovering nor request capture even while dragging over our windows afterward.
+ const bool has_open_popup = (g.OpenPopupStack.Size > 0);
+ const bool has_open_modal = (modal_window != NULL);
+ int mouse_earliest_down = -1;
bool mouse_any_down = false;
- for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
+ for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
{
- if (g.IO.MouseClicked[i])
- g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0);
- mouse_any_down |= g.IO.MouseDown[i];
- if (g.IO.MouseDown[i])
- if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
- mouse_earliest_button_down = i;
+ if (io.MouseClicked[i])
+ {
+ io.MouseDownOwned[i] = (g.HoveredWindow != NULL) || has_open_popup;
+ io.MouseDownOwnedUnlessPopupClose[i] = (g.HoveredWindow != NULL) || has_open_modal;
+ }
+ mouse_any_down |= io.MouseDown[i];
+ if (io.MouseDown[i])
+ if (mouse_earliest_down == -1 || io.MouseClickedTime[i] < io.MouseClickedTime[mouse_earliest_down])
+ mouse_earliest_down = i;
}
- const bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
+ const bool mouse_avail = (mouse_earliest_down == -1) || io.MouseDownOwned[mouse_earliest_down];
+ const bool mouse_avail_unless_popup_close = (mouse_earliest_down == -1) || io.MouseDownOwnedUnlessPopupClose[mouse_earliest_down];
// If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
// FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
- if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
+ if (!mouse_avail && !mouse_dragging_extern_payload)
clear_hovered_windows = true;
if (clear_hovered_windows)
g.HoveredWindow = g.HoveredWindowUnderMovingWindow = NULL;
- // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to Dear ImGui + app)
+ // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to Dear ImGui only, false = dispatch mouse to Dear ImGui + underlying app)
+ // Update io.WantCaptureMouseAllowPopupClose (experimental) to give a chance for app to react to popup closure with a drag
if (g.WantCaptureMouseNextFrame != -1)
- g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
+ {
+ io.WantCaptureMouse = io.WantCaptureMouseUnlessPopupClose = (g.WantCaptureMouseNextFrame != 0);
+ }
else
- g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (g.OpenPopupStack.Size > 0);
+ {
+ io.WantCaptureMouse = (mouse_avail && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_popup;
+ io.WantCaptureMouseUnlessPopupClose = (mouse_avail_unless_popup_close && (g.HoveredWindow != NULL || mouse_any_down)) || has_open_modal;
+ }
- // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
+ // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to Dear ImGui only, false = dispatch keyboard info to Dear ImGui + underlying app)
if (g.WantCaptureKeyboardNextFrame != -1)
- g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
+ io.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
else
- g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
- if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
- g.IO.WantCaptureKeyboard = true;
+ io.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
+ if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
+ io.WantCaptureKeyboard = true;
// Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
- g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
+ io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
}
ImGuiKeyModFlags ImGui::GetMergedKeyModFlags()
@@ -4033,6 +4074,18 @@ void ImGui::NewFrame()
g.DragDropWithinTarget = false;
g.DragDropHoldJustPressedId = 0;
+ // Close popups on focus lost (currently wip/opt-in)
+ //if (g.IO.AppFocusLost)
+ // ClosePopupsExceptModals();
+
+ // Clear buttons state when focus is lost
+ // (this is useful so e.g. releasing Alt after focus loss on Alt-Tab doesn't trigger the Alt menu toggle)
+ if (g.IO.AppFocusLost)
+ {
+ g.IO.ClearInputKeys();
+ g.IO.AppFocusLost = false;
+ }
+
// Update keyboard input state
// Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
g.IO.KeyMods = GetMergedKeyModFlags();
@@ -4472,6 +4525,7 @@ void ImGui::EndFrame()
// Clear Input data for next frame
g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
g.IO.InputQueueCharacters.resize(0);
+ g.IO.KeyModsPrev = g.IO.KeyMods; // doing it here is better than in NewFrame() as we'll tolerate backend writing to KeyMods. If we want to firmly disallow it we should detect it.
memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
CallContextHooks(&g, ImGuiContextHookType_EndFramePost);
@@ -5080,7 +5134,7 @@ void ImGui::EndChild()
ItemAdd(bb, window->ChildId);
RenderNavHighlight(bb, window->ChildId);
- // When browsing a window that has no activable items (scroll only) we keep a highlight on the child
+ // When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
if (window->DC.NavLayersActiveMask == 0 && window == g.NavWindow)
RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin);
}
@@ -5726,9 +5780,11 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl
void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window)
{
window->ParentWindow = parent_window;
- window->RootWindow = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window;
+ window->RootWindow = window->RootWindowPopupTree = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window;
if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip))
window->RootWindow = parent_window->RootWindow;
+ if (parent_window && (flags & ImGuiWindowFlags_Popup))
+ window->RootWindowPopupTree = parent_window->RootWindowPopupTree;
if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)))
window->RootWindowForTitleBarHighlight = parent_window->RootWindowForTitleBarHighlight;
while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened)
@@ -5807,12 +5863,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Add to stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
+ g.CurrentWindow = window;
ImGuiWindowStackData window_stack_data;
window_stack_data.Window = window;
window_stack_data.ParentLastItemDataBackup = g.LastItemData;
+ window_stack_data.StackSizesOnBegin.SetToCurrentState();
g.CurrentWindowStack.push_back(window_stack_data);
- g.CurrentWindow = window;
- window->DC.StackSizesOnBegin.SetToCurrentState();
g.CurrentWindow = NULL;
if (flags & ImGuiWindowFlags_Popup)
@@ -6195,16 +6251,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
}
- // Since 1.71, child window can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call.
+ // Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71)
// When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order.
- // We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping child.
- // We also disabled this when we have dimming overlay behind this specific one child.
- // FIXME: More code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected.
+ // FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493)
{
bool render_decorations_in_parent = false;
if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip)
- if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_window->DrawList->VtxBuffer.Size > 0)
+ {
+ // - We test overlap with the previous child window only (testing all would end up being O(log N) not a good investment here)
+ // - We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping childs
+ ImGuiWindow* previous_child = parent_window->DC.ChildWindows.Size >= 2 ? parent_window->DC.ChildWindows[parent_window->DC.ChildWindows.Size - 2] : NULL;
+ bool previous_child_overlapping = previous_child ? previous_child->Rect().Overlaps(window->Rect()) : false;
+ bool parent_is_empty = parent_window->DrawList->VtxBuffer.Size > 0;
+ if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_is_empty && !previous_child_overlapping)
render_decorations_in_parent = true;
+ }
if (render_decorations_in_parent)
window->DrawList = parent_window->DrawList;
@@ -6422,10 +6483,10 @@ void ImGui::End()
// Pop from window stack
g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup;
- g.CurrentWindowStack.pop_back();
if (window->Flags & ImGuiWindowFlags_Popup)
g.BeginPopupStack.pop_back();
- window->DC.StackSizesOnBegin.CompareWithCurrentState();
+ g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithCurrentState();
+ g.CurrentWindowStack.pop_back();
SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window);
}
@@ -6493,7 +6554,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
g.NavFocusScopeId = 0;
g.NavIdIsAlive = false;
g.NavLayer = ImGuiNavLayer_Main;
- g.NavInitRequest = g.NavMoveRequest = false;
+ g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
//IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL);
}
@@ -6600,29 +6661,38 @@ void ImGui::PopItemFlag()
g.CurrentItemFlags = g.ItemFlagsStack.back();
}
-// PushDisabled()/PopDisabled()
-// - Those can be nested but this cannot be used to enable an already disabled section (a single PushDisabled(true) in the stack is enough to keep things disabled)
-// - Those are not yet exposed in imgui.h because we are unsure of how to alter the style in a way that works for everyone.
-// We may rework this. Hypothetically, a future styling system may set a flag which make widgets use different colors.
+// BeginDisabled()/EndDisabled()
+// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
+// - Visually this is currently altering alpha, but it is expected that in a future styling system this would work differently.
// - Feedback welcome at https://github.com/ocornut/imgui/issues/211
-// - You may trivially implement your own variation of this if needed.
-// Here we test (CurrentItemFlags & ImGuiItemFlags_Disabled) to allow nested PushDisabled() calls.
-void ImGui::PushDisabled(bool disabled)
+// - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it.
+// - Optimized shortcuts instead of PushStyleVar() + PushItemFlag()
+void ImGui::BeginDisabled(bool disabled)
{
ImGuiContext& g = *GImGui;
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
if (!was_disabled && disabled)
- PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.6f);
- PushItemFlag(ImGuiItemFlags_Disabled, was_disabled || disabled);
+ {
+ g.DisabledAlphaBackup = g.Style.Alpha;
+ g.Style.Alpha *= g.Style.DisabledAlpha; // PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * g.Style.DisabledAlpha);
+ }
+ if (was_disabled || disabled)
+ g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
+ g.ItemFlagsStack.push_back(g.CurrentItemFlags);
+ g.DisabledStackSize++;
}
-void ImGui::PopDisabled()
+void ImGui::EndDisabled()
{
ImGuiContext& g = *GImGui;
+ IM_ASSERT(g.DisabledStackSize > 0);
+ g.DisabledStackSize--;
bool was_disabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
- PopItemFlag();
+ //PopItemFlag();
+ g.ItemFlagsStack.pop_back();
+ g.CurrentItemFlags = g.ItemFlagsStack.back();
if (was_disabled && (g.CurrentItemFlags & ImGuiItemFlags_Disabled) == 0)
- PopStyleVar();
+ g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar();
}
// FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system.
@@ -6660,14 +6730,25 @@ void ImGui::PopTextWrapPos()
window->DC.TextWrapPosStack.pop_back();
}
-bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
+static ImGuiWindow* GetCombinedRootWindow(ImGuiWindow* window, bool popup_hierarchy)
+{
+ window = window->RootWindow;
+ if (popup_hierarchy)
+ window = window->RootWindowPopupTree;
+ return window;
+}
+
+bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy)
{
- if (window->RootWindow == potential_parent)
+ ImGuiWindow* window_root = GetCombinedRootWindow(window, popup_hierarchy);
+ if (window_root == potential_parent)
return true;
while (window != NULL)
{
if (window == potential_parent)
return true;
+ if (window == window_root) // end of chain
+ return false;
window = window->ParentWindow;
}
return false;
@@ -6691,37 +6772,31 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
{
IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function
ImGuiContext& g = *GImGui;
- if (g.HoveredWindow == NULL)
+ ImGuiWindow* ref_window = g.HoveredWindow;
+ ImGuiWindow* cur_window = g.CurrentWindow;
+ if (ref_window == NULL)
return false;
if ((flags & ImGuiHoveredFlags_AnyWindow) == 0)
{
- ImGuiWindow* window = g.CurrentWindow;
- switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows))
- {
- case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows:
- if (g.HoveredWindow->RootWindow != window->RootWindow)
- return false;
- break;
- case ImGuiHoveredFlags_RootWindow:
- if (g.HoveredWindow != window->RootWindow)
- return false;
- break;
- case ImGuiHoveredFlags_ChildWindows:
- if (!IsWindowChildOf(g.HoveredWindow, window))
- return false;
- break;
- default:
- if (g.HoveredWindow != window)
- return false;
- break;
- }
+ IM_ASSERT(cur_window); // Not inside a Begin()/End()
+ const bool popup_hierarchy = (flags & ImGuiHoveredFlags_NoPopupHierarchy) == 0;
+ if (flags & ImGuiHoveredFlags_RootWindow)
+ cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy);
+
+ bool result;
+ if (flags & ImGuiHoveredFlags_ChildWindows)
+ result = IsWindowChildOf(ref_window, cur_window, popup_hierarchy);
+ else
+ result = (ref_window == cur_window);
+ if (!result)
+ return false;
}
- if (!IsWindowContentHoverable(g.HoveredWindow, flags))
+ if (!IsWindowContentHoverable(ref_window, flags))
return false;
if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
- if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != g.HoveredWindow->MoveId)
+ if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != ref_window->MoveId)
return false;
return true;
}
@@ -6729,22 +6804,23 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags)
{
ImGuiContext& g = *GImGui;
+ ImGuiWindow* ref_window = g.NavWindow;
+ ImGuiWindow* cur_window = g.CurrentWindow;
+ if (ref_window == NULL)
+ return false;
if (flags & ImGuiFocusedFlags_AnyWindow)
- return g.NavWindow != NULL;
+ return true;
+ IM_ASSERT(cur_window); // Not inside a Begin()/End()
- IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End()
- switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows))
- {
- case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows:
- return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow;
- case ImGuiFocusedFlags_RootWindow:
- return g.NavWindow == g.CurrentWindow->RootWindow;
- case ImGuiFocusedFlags_ChildWindows:
- return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow);
- default:
- return g.NavWindow == g.CurrentWindow;
- }
+ const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0;
+ if (flags & ImGuiHoveredFlags_RootWindow)
+ cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy);
+
+ if (flags & ImGuiHoveredFlags_ChildWindows)
+ return IsWindowChildOf(ref_window, cur_window, popup_hierarchy);
+ else
+ return (ref_window == cur_window);
}
// Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext)
@@ -7014,6 +7090,7 @@ void ImGui::ActivateItem(ImGuiID id)
{
ImGuiContext& g = *GImGui;
g.NavNextActivateId = id;
+ g.NavNextActivateFlags = ImGuiActivateFlags_None;
}
void ImGui::PushFocusScope(ImGuiID id)
@@ -7267,53 +7344,13 @@ void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, voi
{
// PVS-Studio V1044 is "Loop break conditions do not depend on the number of iterations"
ImGuiContext& g = *GImGui;
- while (g.CurrentWindowStack.Size > 0)
+ while (g.CurrentWindowStack.Size > 0) //-V1044
{
- while (g.CurrentTable && (g.CurrentTable->OuterWindow == g.CurrentWindow || g.CurrentTable->InnerWindow == g.CurrentWindow))
- {
- if (log_callback) log_callback(user_data, "Recovered from missing EndTable() in '%s'", g.CurrentTable->OuterWindow->Name);
- EndTable();
- }
+ ErrorCheckEndWindowRecover(log_callback, user_data);
ImGuiWindow* window = g.CurrentWindow;
- IM_ASSERT(window != NULL);
- while (g.CurrentTabBar != NULL) //-V1044
- {
- if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name);
- EndTabBar();
- }
- while (window->DC.TreeDepth > 0)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name);
- TreePop();
- }
- while (g.GroupStack.Size > window->DC.StackSizesOnBegin.SizeOfGroupStack)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing EndGroup() in '%s'", window->Name);
- EndGroup();
- }
- while (window->IDStack.Size > 1)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing PopID() in '%s'", window->Name);
- PopID();
- }
- while (g.ColorStack.Size > window->DC.StackSizesOnBegin.SizeOfColorStack)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing PopStyleColor() in '%s' for ImGuiCol_%s", window->Name, GetStyleColorName(g.ColorStack.back().Col));
- PopStyleColor();
- }
- while (g.StyleVarStack.Size > window->DC.StackSizesOnBegin.SizeOfStyleVarStack)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name);
- PopStyleVar();
- }
- while (g.FocusScopeStack.Size > window->DC.StackSizesOnBegin.SizeOfFocusScopeStack)
- {
- if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name);
- PopFocusScope();
- }
if (g.CurrentWindowStack.Size == 1)
{
- IM_ASSERT(g.CurrentWindow->IsFallbackWindow);
+ IM_ASSERT(window->IsFallbackWindow);
break;
}
IM_ASSERT(window == g.CurrentWindow);
@@ -7330,6 +7367,66 @@ void ImGui::ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, voi
}
}
+// Must be called before End()/EndChild()
+void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data)
+{
+ ImGuiContext& g = *GImGui;
+ while (g.CurrentTable && (g.CurrentTable->OuterWindow == g.CurrentWindow || g.CurrentTable->InnerWindow == g.CurrentWindow))
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing EndTable() in '%s'", g.CurrentTable->OuterWindow->Name);
+ EndTable();
+ }
+
+ ImGuiWindow* window = g.CurrentWindow;
+ ImGuiStackSizes* stack_sizes = &g.CurrentWindowStack.back().StackSizesOnBegin;
+ IM_ASSERT(window != NULL);
+ while (g.CurrentTabBar != NULL) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing EndTabBar() in '%s'", window->Name);
+ EndTabBar();
+ }
+ while (window->DC.TreeDepth > 0)
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing TreePop() in '%s'", window->Name);
+ TreePop();
+ }
+ while (g.GroupStack.Size > stack_sizes->SizeOfGroupStack) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing EndGroup() in '%s'", window->Name);
+ EndGroup();
+ }
+ while (window->IDStack.Size > 1)
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing PopID() in '%s'", window->Name);
+ PopID();
+ }
+ while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name);
+ EndDisabled();
+ }
+ while (g.ColorStack.Size > stack_sizes->SizeOfColorStack)
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing PopStyleColor() in '%s' for ImGuiCol_%s", window->Name, GetStyleColorName(g.ColorStack.back().Col));
+ PopStyleColor();
+ }
+ while (g.ItemFlagsStack.Size > stack_sizes->SizeOfItemFlagsStack) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing PopItemFlag() in '%s'", window->Name);
+ PopItemFlag();
+ }
+ while (g.StyleVarStack.Size > stack_sizes->SizeOfStyleVarStack) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing PopStyleVar() in '%s'", window->Name);
+ PopStyleVar();
+ }
+ while (g.FocusScopeStack.Size > stack_sizes->SizeOfFocusScopeStack) //-V1044
+ {
+ if (log_callback) log_callback(user_data, "Recovered from missing PopFocusScope() in '%s'", window->Name);
+ PopFocusScope();
+ }
+}
+
// Save current stack sizes for later compare
void ImGuiStackSizes::SetToCurrentState()
{
@@ -7341,7 +7438,9 @@ void ImGuiStackSizes::SetToCurrentState()
SizeOfFontStack = (short)g.FontStack.Size;
SizeOfFocusScopeStack = (short)g.FocusScopeStack.Size;
SizeOfGroupStack = (short)g.GroupStack.Size;
+ SizeOfItemFlagsStack = (short)g.ItemFlagsStack.Size;
SizeOfBeginPopupStack = (short)g.BeginPopupStack.Size;
+ SizeOfDisabledStack = (short)g.DisabledStackSize;
}
// Compare to detect usage errors
@@ -7359,6 +7458,8 @@ void ImGuiStackSizes::CompareWithCurrentState()
// For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them.
IM_ASSERT(SizeOfGroupStack == g.GroupStack.Size && "BeginGroup/EndGroup Mismatch!");
IM_ASSERT(SizeOfBeginPopupStack == g.BeginPopupStack.Size && "BeginPopup/EndPopup or BeginMenu/EndMenu Mismatch!");
+ IM_ASSERT(SizeOfDisabledStack == g.DisabledStackSize && "BeginDisabled/EndDisabled Mismatch!");
+ IM_ASSERT(SizeOfItemFlagsStack >= g.ItemFlagsStack.Size && "PushItemFlag/PopItemFlag Mismatch!");
IM_ASSERT(SizeOfColorStack >= g.ColorStack.Size && "PushStyleColor/PopStyleColor Mismatch!");
IM_ASSERT(SizeOfStyleVarStack >= g.StyleVarStack.Size && "PushStyleVar/PopStyleVar Mismatch!");
IM_ASSERT(SizeOfFontStack >= g.FontStack.Size && "PushFont/PopFont Mismatch!");
@@ -7393,7 +7494,6 @@ void ImGuiStackSizes::CompareWithCurrentState()
// - GetContentRegionMaxAbs() [Internal]
// - GetContentRegionAvail(),
// - GetWindowContentRegionMin(), GetWindowContentRegionMax()
-// - GetWindowContentRegionWidth()
// - BeginGroup()
// - EndGroup()
// Also see in imgui_widgets: tab bars, columns.
@@ -7443,15 +7543,17 @@ void ImGui::ItemSize(const ImRect& bb, float text_baseline_y)
// Declare item bounding box for clipping and interaction.
// Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
-bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemAddFlags flags)
+bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemFlags extra_flags)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
// Set item data
+ // (DisplayRect is left untouched, made valid when ImGuiItemStatusFlags_HasDisplayRect is set)
g.LastItemData.ID = id;
g.LastItemData.Rect = bb;
- g.LastItemData.InFlags = g.CurrentItemFlags;
+ g.LastItemData.NavRect = nav_bb_arg ? *nav_bb_arg : bb;
+ g.LastItemData.InFlags = g.CurrentItemFlags | extra_flags;
g.LastItemData.StatusFlags = ImGuiItemStatusFlags_None;
// Directional navigation processing
@@ -7470,7 +7572,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
if (g.NavId == id || g.NavAnyRequest)
if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
- NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id);
+ NavProcessItem();
// [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd()
#ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
@@ -7489,15 +7591,15 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu
#endif
// Clipping test
- const bool is_clipped = IsClippedEx(bb, id, false);
+ const bool is_clipped = IsClippedEx(bb, id);
if (is_clipped)
return false;
//if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
- // Tab stop handling (previously was using internal ItemFocusable() api)
- // FIXME-NAV: We would now want to move this above the clipping test, but this would require being able to scroll and currently this would mean an extra frame. (#4079, #343)
- if (flags & ImGuiItemAddFlags_Focusable)
- ItemFocusable(window, id);
+ // [WIP] Tab stop handling (previously was using internal FocusableItemRegister() api)
+ // FIXME-NAV: We would now want to move this before the clipping test, but this would require being able to scroll and currently this would mean an extra frame. (#4079, #343)
+ if (extra_flags & ImGuiItemFlags_Inputable)
+ ItemInputable(window, id);
// We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
if (IsMouseHoveringRect(bb.Min, bb.Max))
@@ -7761,14 +7863,9 @@ ImVec2 ImGui::GetWindowContentRegionMax()
return window->ContentRegionRect.Max - window->Pos;
}
-float ImGui::GetWindowContentRegionWidth()
-{
- ImGuiWindow* window = GImGui->CurrentWindow;
- return window->ContentRegionRect.GetWidth();
-}
-
// Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
// Groups are currently a mishmash of functionalities which should perhaps be clarified and separated.
+// FIXME-OPT: Could we safely early out on ->SkipItems?
void ImGui::BeginGroup()
{
ImGuiContext& g = *GImGui;
@@ -8284,6 +8381,21 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to
}
}
+void ImGui::ClosePopupsExceptModals()
+{
+ ImGuiContext& g = *GImGui;
+
+ int popup_count_to_keep;
+ for (popup_count_to_keep = g.OpenPopupStack.Size; popup_count_to_keep > 0; popup_count_to_keep--)
+ {
+ ImGuiWindow* window = g.OpenPopupStack[popup_count_to_keep - 1].Window;
+ if (!window || window->Flags & ImGuiWindowFlags_Modal)
+ break;
+ }
+ if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below
+ ClosePopupToLevel(popup_count_to_keep, true);
+}
+
void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
{
ImGuiContext& g = *GImGui;
@@ -8419,7 +8531,7 @@ void ImGui::EndPopup()
IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls
IM_ASSERT(g.BeginPopupStack.Size > 0);
- // Make all menus and popups wrap around for now, may need to expose that policy.
+ // Make all menus and popups wrap around for now, may need to expose that policy (e.g. focus scope could include wrap/loop policy flags used by new move requests)
if (g.NavWindow == window)
NavMoveRequestTryWrapping(window, ImGuiNavMoveFlags_LoopY);
@@ -8639,6 +8751,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
//-----------------------------------------------------------------------------
// FIXME-NAV: The existence of SetNavID vs SetFocusID properly needs to be clarified/reworked.
+// In our terminology those should be interchangeable. Those two functions are merely a legacy artifact, so at minimum naming should be clarified.
void ImGui::SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
{
ImGuiContext& g = *GImGui;
@@ -8669,7 +8782,7 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
window->NavLastIds[nav_layer] = id;
if (g.LastItemData.ID == id)
- window->NavRectRel[nav_layer] = ImRect(g.LastItemData.Rect.Min - window->Pos, g.LastItemData.Rect.Max - window->Pos);
+ window->NavRectRel[nav_layer] = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos);
if (g.ActiveIdSource == ImGuiInputSource_Nav)
g.NavDisableMouseHover = true;
@@ -8700,7 +8813,7 @@ static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect
r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y);
r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y);
}
- else
+ else // FIXME: PageUp/PageDown are leaving move_dir == None
{
r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x);
r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x);
@@ -8708,15 +8821,17 @@ static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect
}
// Scoring function for gamepad/keyboard directional navigation. Based on https://gist.github.com/rygorous/6981057
-static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
+static bool ImGui::NavScoreItem(ImGuiNavItemData* result)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (g.NavLayer != window->DC.NavLayerCurrent)
return false;
- const ImRect& curr = g.NavScoringRect; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width)
- g.NavScoringCount++;
+ // FIXME: Those are not good variables names
+ ImRect cand = g.LastItemData.NavRect; // Current item nav rectangle
+ const ImRect curr = g.NavScoringRect; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width)
+ g.NavScoringDebugCount++;
// When entering through a NavFlattened border, we consider child window items as fully clipped for scoring
if (window->ParentWindow == g.NavWindow)
@@ -8778,24 +8893,24 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
draw_list->AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40,0,0,150));
- draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf);
+ draw_list->AddText(cand.Max, ~0U, buf);
}
else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate.
{
- if (IsKeyPressedMap(ImGuiKey_C)) { g.NavMoveDirLast = (ImGuiDir)((g.NavMoveDirLast + 1) & 3); g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_C]] = 0.01f; }
if (quadrant == g.NavMoveDir)
{
ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
ImDrawList* draw_list = GetForegroundDrawList(window);
draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
- draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf);
+ draw_list->AddText(cand.Min, IM_COL32(255, 255, 255, 255), buf);
}
}
#endif
// Is it in the quadrant we're interesting in moving to?
bool new_best = false;
- if (quadrant == g.NavMoveDir)
+ const ImGuiDir move_dir = g.NavMoveDir;
+ if (quadrant == move_dir)
{
// Does it beat the current best candidate?
if (dist_box < result->DistBox)
@@ -8817,7 +8932,7 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
// Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items
// (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index),
// this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis.
- if (((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance
+ if (((move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance
new_best = true;
}
}
@@ -8830,7 +8945,7 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
// Disabling it may lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option?
if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match
if (g.NavLayer == ImGuiNavLayer_Menu && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
- if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f))
+ if ((move_dir == ImGuiDir_Left && dax < 0.0f) || (move_dir == ImGuiDir_Right && dax > 0.0f) || (move_dir == ImGuiDir_Up && day < 0.0f) || (move_dir == ImGuiDir_Down && day > 0.0f))
{
result->DistAxial = dist_axial;
new_best = true;
@@ -8839,23 +8954,25 @@ static bool ImGui::NavScoreItem(ImGuiNavItemData* result, ImRect cand)
return new_best;
}
-static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result, ImGuiWindow* window, ImGuiID id, const ImRect& nav_bb_rel)
+static void ImGui::NavApplyItemToResult(ImGuiNavItemData* result)
{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = g.CurrentWindow;
result->Window = window;
- result->ID = id;
+ result->ID = g.LastItemData.ID;
result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
- result->RectRel = nav_bb_rel;
+ result->RectRel = ImRect(g.LastItemData.NavRect.Min - window->Pos, g.LastItemData.NavRect.Max - window->Pos);
}
// We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
-static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id)
+// This is called after LastItemData is set.
+static void ImGui::NavProcessItem()
{
ImGuiContext& g = *GImGui;
- //if (!g.IO.NavActive) // [2017/10/06] Removed this possibly redundant test but I am not sure of all the side-effects yet. Some of the feature here will need to work regardless of using a _NoNavInputs flag.
- // return;
-
+ ImGuiWindow* window = g.CurrentWindow;
+ const ImGuiID id = g.LastItemData.ID;
+ const ImRect nav_bb = g.LastItemData.NavRect;
const ImGuiItemFlags item_flags = g.LastItemData.InFlags;
- const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
// Process Init Request
if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent)
@@ -8865,7 +8982,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
if (candidate_for_nav_default_focus || g.NavInitResultId == 0)
{
g.NavInitResultId = id;
- g.NavInitResultRectRel = nav_bb_rel;
+ g.NavInitResultRectRel = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
}
if (candidate_for_nav_default_focus)
{
@@ -8875,27 +8992,22 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
}
// Process Move Request (scoring for navigation)
- // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRectScreen + scoring from a rect wrapped according to current wrapping policy)
- if ((g.NavId != id || (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav)))
+ // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy)
+ if (g.NavMoveScoringItems)
{
- ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
-#if IMGUI_DEBUG_NAV_SCORING
- // [DEBUG] Score all items in NavWindow at all times
- if (!g.NavMoveRequest)
- g.NavMoveDir = g.NavMoveDirLast;
- bool new_best = NavScoreItem(result, nav_bb) && g.NavMoveRequest;
-#else
- bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb);
-#endif
- if (new_best)
- NavApplyItemToResult(result, window, id, nav_bb_rel);
+ if ((g.NavId != id || (g.NavMoveFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNav)))
+ {
+ ImGuiNavItemData* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
+ if (NavScoreItem(result))
+ NavApplyItemToResult(result);
- // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
- const float VISIBLE_RATIO = 0.70f;
- if ((g.NavMoveRequestFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
- if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
- if (NavScoreItem(&g.NavMoveResultLocalVisibleSet, nav_bb))
- NavApplyItemToResult(&g.NavMoveResultLocalVisibleSet, window, id, nav_bb_rel);
+ // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
+ const float VISIBLE_RATIO = 0.70f;
+ if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
+ if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
+ if (NavScoreItem(&g.NavMoveResultLocalVisible))
+ NavApplyItemToResult(&g.NavMoveResultLocalVisible);
+ }
}
// Update window-relative bounding box of navigated item
@@ -8905,43 +9017,62 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con
g.NavLayer = window->DC.NavLayerCurrent;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
g.NavIdIsAlive = true;
- window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position)
+ window->NavRectRel[window->DC.NavLayerCurrent] = ImRect(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); // Store item bounding box (relative to window position)
}
}
bool ImGui::NavMoveRequestButNoResultYet()
{
ImGuiContext& g = *GImGui;
- return g.NavMoveRequest && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0;
+ return g.NavMoveScoringItems && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0;
+}
+
+// FIXME: ScoringRect is not set
+void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags)
+{
+ ImGuiContext& g = *GImGui;
+ IM_ASSERT(g.NavWindow != NULL);
+ g.NavMoveSubmitted = g.NavMoveScoringItems = true;
+ g.NavMoveDir = move_dir;
+ g.NavMoveDirForDebug = move_dir;
+ g.NavMoveClipDir = clip_dir;
+ g.NavMoveFlags = move_flags;
+ g.NavMoveForwardToNextFrame = false;
+ g.NavMoveKeyMods = g.IO.KeyMods;
+ g.NavMoveResultLocal.Clear();
+ g.NavMoveResultLocalVisible.Clear();
+ g.NavMoveResultOther.Clear();
+ NavUpdateAnyRequestFlag();
}
void ImGui::NavMoveRequestCancel()
{
ImGuiContext& g = *GImGui;
- g.NavMoveRequest = false;
+ g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
-void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags)
+// Forward will reuse the move request again on the next frame (generally with modifications done to it)
+void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags)
{
ImGuiContext& g = *GImGui;
- IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
+ IM_ASSERT(g.NavMoveForwardToNextFrame == false);
NavMoveRequestCancel();
+ g.NavMoveForwardToNextFrame = true;
g.NavMoveDir = move_dir;
g.NavMoveClipDir = clip_dir;
- g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
- g.NavMoveRequestFlags = move_flags;
- g.NavWindow->NavRectRel[g.NavLayer] = bb_rel;
+ g.NavMoveFlags = move_flags | ImGuiNavMoveFlags_Forwarded;
}
-void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags)
+// Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire
+// popup is assembled and in case of appended popups it is not clear which EndPopup() call is final.
+void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wrap_flags)
{
ImGuiContext& g = *GImGui;
-
- // Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire
- // popup is assembled and in case of appended popups it is not clear which EndPopup() call is final.
- g.NavWrapRequestWindow = window;
- g.NavWrapRequestFlags = move_flags;
+ IM_ASSERT(wrap_flags != 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY
+ // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test
+ if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main)
+ g.NavMoveFlags |= wrap_flags;
}
// FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
@@ -8973,20 +9104,20 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
if (window->NavLastIds[layer] != 0)
{
SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
- g.NavDisableHighlight = false;
- g.NavDisableMouseHover = g.NavMousePosDirty = true;
}
else
{
g.NavLayer = layer;
NavInitWindow(window, true);
}
+ g.NavDisableHighlight = false;
+ g.NavDisableMouseHover = g.NavMousePosDirty = true;
}
static inline void ImGui::NavUpdateAnyRequestFlag()
{
ImGuiContext& g = *GImGui;
- g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || (IMGUI_DEBUG_NAV_SCORING && g.NavWindow != NULL);
+ g.NavAnyRequest = g.NavMoveScoringItems || g.NavInitRequest || (IMGUI_DEBUG_NAV_SCORING && g.NavWindow != NULL);
if (g.NavAnyRequest)
IM_ASSERT(g.NavWindow != NULL);
}
@@ -9031,7 +9162,7 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
// Mouse (we need a fallback in case the mouse becomes invalid after being used)
if (IsMousePosValid(&g.IO.MousePos))
return g.IO.MousePos;
- return g.LastValidMousePos;
+ return g.MouseLastValidPos;
}
else
{
@@ -9087,16 +9218,12 @@ static void ImGui::NavUpdate()
ImGuiIO& io = g.IO;
io.WantSetMousePos = false;
- g.NavWrapRequestWindow = NULL;
- g.NavWrapRequestFlags = ImGuiNavMoveFlags_None;
-#if 0
- if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
-#endif
+ //if (g.NavScoringDebugCount > 0) IMGUI_DEBUG_LOG("NavScoringDebugCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.NavScoringDebugCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
// Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard)
// (do it before we map Keyboard input!)
- bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
- bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
+ const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
+ const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
if (nav_gamepad_active && g.NavInputSource != ImGuiInputSource_Gamepad)
{
if (io.NavInputs[ImGuiNavInput_Activate] > 0.0f || io.NavInputs[ImGuiNavInput_Input] > 0.0f || io.NavInputs[ImGuiNavInput_Cancel] > 0.0f || io.NavInputs[ImGuiNavInput_Menu] > 0.0f
@@ -9119,16 +9246,6 @@ static void ImGui::NavUpdate()
io.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
if (io.KeyShift)
io.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
-
- // AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl)
- // But also even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
- if (io.KeyAlt && !io.KeyCtrl)
- io.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f;
-
- // We automatically cancel toggling nav layer when any text has been typed while holding Alt. (See #370)
- if (io.KeyAlt && !io.KeyCtrl && g.NavWindowingToggleLayer && io.InputQueueCharacters.Size > 0)
- g.NavWindowingToggleLayer = false;
-
#undef NAV_MAP_KEY
}
memcpy(io.NavInputsDownDurationPrev, io.NavInputsDownDuration, sizeof(io.NavInputsDownDuration));
@@ -9137,24 +9254,16 @@ static void ImGui::NavUpdate()
// Process navigation init request (select first/default focus)
if (g.NavInitResultId != 0)
- NavUpdateInitResult();
+ NavInitRequestApplyResult();
g.NavInitRequest = false;
g.NavInitRequestFromMove = false;
g.NavInitResultId = 0;
g.NavJustMovedToId = 0;
// Process navigation move request
- if (g.NavMoveRequest)
- NavUpdateMoveResult();
-
- // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame
- if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
- {
- IM_ASSERT(g.NavMoveRequest);
- if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
- g.NavDisableHighlight = false;
- g.NavMoveRequestForward = ImGuiNavForward_None;
- }
+ if (g.NavMoveSubmitted)
+ NavMoveRequestApplyResult();
+ g.NavMoveSubmitted = g.NavMoveScoringItems = false;
// Apply application mouse position movement, after we had a chance to process move request result.
if (g.NavMousePosDirty && g.NavIdIsAlive)
@@ -9165,6 +9274,7 @@ static void ImGui::NavUpdate()
{
io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos();
io.WantSetMousePos = true;
+ //IMGUI_DEBUG_LOG("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y);
}
g.NavMousePosDirty = false;
}
@@ -9172,7 +9282,7 @@ static void ImGui::NavUpdate()
g.NavJustTabbedId = 0;
IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
- // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0
+ // Store our return window (for returning from Menu Layer to Main Layer) and clear it as soon as we step back in our own Layer 0
if (g.NavWindow)
NavSaveLastChildNavWindowIntoParent(g.NavWindow);
if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == ImGuiNavLayer_Main)
@@ -9186,116 +9296,51 @@ static void ImGui::NavUpdate()
io.NavVisible = (io.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL);
// Process NavCancel input (to close a popup, get back to parent, clear focus)
- if (IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed))
- {
- IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
- if (g.ActiveId != 0)
- {
- if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel))
- ClearActiveID();
- }
- else if (g.NavLayer != ImGuiNavLayer_Main)
- {
- // Leave the "menu" layer
- NavRestoreLayer(ImGuiNavLayer_Main);
- }
- else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
- {
- // Exit child window
- ImGuiWindow* child_window = g.NavWindow;
- ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
- IM_ASSERT(child_window->ChildId != 0);
- ImRect child_rect = child_window->Rect();
- FocusWindow(parent_window);
- SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos));
- }
- else if (g.OpenPopupStack.Size > 0)
- {
- // Close open popup/menu
- if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
- ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
- }
- else
- {
- // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
- if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
- g.NavWindow->NavLastIds[0] = 0;
- g.NavId = g.NavFocusScopeId = 0;
- }
- }
+ NavUpdateCancelRequest();
// Process manual activation request
- g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0;
+ g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavActivateInputId = 0;
+ g.NavActivateFlags = ImGuiActivateFlags_None;
if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
{
bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
+ bool input_down = IsNavInputDown(ImGuiNavInput_Input);
bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed);
+ bool input_pressed = input_down && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed);
if (g.ActiveId == 0 && activate_pressed)
+ {
g.NavActivateId = g.NavId;
+ g.NavActivateFlags = ImGuiActivateFlags_PreferTweak;
+ }
+ if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && input_pressed)
+ {
+ g.NavActivateInputId = g.NavId;
+ g.NavActivateFlags = ImGuiActivateFlags_PreferInput;
+ }
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down)
g.NavActivateDownId = g.NavId;
if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed)
g.NavActivatePressedId = g.NavId;
- if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed))
- g.NavInputId = g.NavId;
}
if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
g.NavDisableHighlight = true;
if (g.NavActivateId != 0)
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
- g.NavMoveRequest = false;
// Process programmatic activation request
+ // FIXME-NAV: Those should eventually be queued (unlike focus they don't cancel each others)
if (g.NavNextActivateId != 0)
- g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId;
- g.NavNextActivateId = 0;
-
- // Initiate directional inputs request
- if (g.NavMoveRequestForward == ImGuiNavForward_None)
- {
- g.NavMoveDir = ImGuiDir_None;
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
- if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
- {
- const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat;
- if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
- if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
- if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
- if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; }
- }
- g.NavMoveClipDir = g.NavMoveDir;
- }
- else
{
- // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
- // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function)
- IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
- IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued);
- IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
- g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
+ if (g.NavNextActivateFlags & ImGuiActivateFlags_PreferInput)
+ g.NavActivateInputId = g.NavNextActivateId;
+ else
+ g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavNextActivateId;
+ g.NavActivateFlags = g.NavNextActivateFlags;
}
+ g.NavNextActivateId = 0;
- // Update PageUp/PageDown/Home/End scroll
- // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
- float nav_scoring_rect_offset_y = 0.0f;
- if (nav_keyboard_active)
- nav_scoring_rect_offset_y = NavUpdatePageUpPageDown();
-
- // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match
- if (g.NavMoveDir != ImGuiDir_None)
- {
- g.NavMoveRequest = true;
- g.NavMoveRequestKeyMods = io.KeyMods;
- g.NavMoveDirLast = g.NavMoveDir;
- }
- if (g.NavMoveRequest && g.NavId == 0)
- {
- IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
- g.NavInitRequest = g.NavInitRequestFromMove = true;
- // Reassigning with same value, we're being explicit here.
- g.NavInitResultId = 0; // -V1048
- g.NavDisableHighlight = false;
- }
+ // Process move requests
+ NavUpdateCreateMoveRequest();
NavUpdateAnyRequestFlag();
// Scrolling
@@ -9304,12 +9349,13 @@ static void ImGui::NavUpdate()
// *Fallback* manual-scroll with Nav directional keys when window has no navigable item
ImGuiWindow* window = g.NavWindow;
const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * io.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
- if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest)
+ const ImGuiDir move_dir = g.NavMoveDir;
+ if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll && move_dir != ImGuiDir_None)
{
- if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right)
- SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
- if (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down)
- SetScrollY(window, ImFloor(window->Scroll.y + ((g.NavMoveDir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed));
+ if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
+ SetScrollX(window, ImFloor(window->Scroll.x + ((move_dir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
+ if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down)
+ SetScrollY(window, ImFloor(window->Scroll.y + ((move_dir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed));
}
// *Normal* Manual scroll with NavScrollXXX keys
@@ -9321,37 +9367,15 @@ static void ImGui::NavUpdate()
SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
}
- // Reset search results
- g.NavMoveResultLocal.Clear();
- g.NavMoveResultLocalVisibleSet.Clear();
- g.NavMoveResultOther.Clear();
-
- // When using gamepad, we project the reference nav bounding box into window visible area.
- // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative
- // (can't focus a visible object like we can with the mouse).
- if (g.NavMoveRequest && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main)
+ // Always prioritize mouse highlight if navigation is disabled
+ if (!nav_keyboard_active && !nav_gamepad_active)
{
- ImGuiWindow* window = g.NavWindow;
- ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1));
- if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
- {
- IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n");
- float pad = window->CalcFontSize() * 0.5f;
- window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
- window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel);
- g.NavId = g.NavFocusScopeId = 0;
- }
+ g.NavDisableHighlight = true;
+ g.NavDisableMouseHover = g.NavMousePosDirty = false;
}
- // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
- ImRect nav_rect_rel = g.NavWindow && !g.NavWindow->NavRectRel[g.NavLayer].IsInverted() ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0);
- g.NavScoringRect = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : ImRect(0, 0, 0, 0);
- g.NavScoringRect.TranslateY(nav_scoring_rect_offset_y);
- g.NavScoringRect.Min.x = ImMin(g.NavScoringRect.Min.x + 1.0f, g.NavScoringRect.Max.x);
- g.NavScoringRect.Max.x = g.NavScoringRect.Min.x;
- IM_ASSERT(!g.NavScoringRect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
- //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
- g.NavScoringCount = 0;
+ // [DEBUG]
+ g.NavScoringDebugCount = 0;
#if IMGUI_DEBUG_NAV_RECTS
if (g.NavWindow)
{
@@ -9362,7 +9386,7 @@ static void ImGui::NavUpdate()
#endif
}
-static void ImGui::NavUpdateInitResult()
+void ImGui::NavInitRequestApplyResult()
{
// In very rare cases g.NavWindow may be null (e.g. clearing focus after requesting an init request, which does happen when releasing Alt while clicking on void)
ImGuiContext& g = *GImGui;
@@ -9373,6 +9397,7 @@ static void ImGui::NavUpdateInitResult()
// FIXME-NAV: On _NavFlattened windows, g.NavWindow will only be updated during subsequent frame. Not a problem currently.
IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name);
SetNavID(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
+ g.NavIdIsAlive = true; // Mark as alive from previous frame as we got a result
if (g.NavInitRequestFromMove)
{
g.NavDisableHighlight = false;
@@ -9380,13 +9405,114 @@ static void ImGui::NavUpdateInitResult()
}
}
-// Apply result from previous frame navigation directional move request
-static void ImGui::NavUpdateMoveResult()
+void ImGui::NavUpdateCreateMoveRequest()
{
ImGuiContext& g = *GImGui;
- if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
+ ImGuiIO& io = g.IO;
+ ImGuiWindow* window = g.NavWindow;
+
+ if (g.NavMoveForwardToNextFrame && window != NULL)
+ {
+ // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
+ // (preserve most state, which were already set by the NavMoveRequestForward() function)
+ IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
+ IM_ASSERT(g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded);
+ IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
+ }
+ else
+ {
+ // Initiate directional inputs request
+ g.NavMoveDir = ImGuiDir_None;
+ g.NavMoveFlags = ImGuiNavMoveFlags_None;
+ if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs))
+ {
+ const ImGuiInputReadMode read_mode = ImGuiInputReadMode_Repeat;
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && (IsNavInputTest(ImGuiNavInput_DpadLeft, read_mode) || IsNavInputTest(ImGuiNavInput_KeyLeft_, read_mode))) { g.NavMoveDir = ImGuiDir_Left; }
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && (IsNavInputTest(ImGuiNavInput_DpadRight, read_mode) || IsNavInputTest(ImGuiNavInput_KeyRight_, read_mode))) { g.NavMoveDir = ImGuiDir_Right; }
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && (IsNavInputTest(ImGuiNavInput_DpadUp, read_mode) || IsNavInputTest(ImGuiNavInput_KeyUp_, read_mode))) { g.NavMoveDir = ImGuiDir_Up; }
+ if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && (IsNavInputTest(ImGuiNavInput_DpadDown, read_mode) || IsNavInputTest(ImGuiNavInput_KeyDown_, read_mode))) { g.NavMoveDir = ImGuiDir_Down; }
+ }
+ g.NavMoveClipDir = g.NavMoveDir;
+ }
+
+ // Update PageUp/PageDown/Home/End scroll
+ // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
+ const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
+ float scoring_rect_offset_y = 0.0f;
+ if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active)
+ scoring_rect_offset_y = NavUpdatePageUpPageDown();
+
+ // [DEBUG] Always send a request
+#if IMGUI_DEBUG_NAV_SCORING
+ if (io.KeyCtrl && IsKeyPressedMap(ImGuiKey_C))
+ g.NavMoveDirForDebug = (ImGuiDir)((g.NavMoveDirForDebug + 1) & 3);
+ if (io.KeyCtrl && g.NavMoveDir == ImGuiDir_None)
+ {
+ g.NavMoveDir = g.NavMoveDirForDebug;
+ g.NavMoveFlags |= ImGuiNavMoveFlags_DebugNoResult;
+ }
+#endif
+
+ // Submit
+ g.NavMoveForwardToNextFrame = false;
+ if (g.NavMoveDir != ImGuiDir_None)
+ NavMoveRequestSubmit(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags);
+
+ // Moving with no reference triggers a init request (will be used as a fallback if the direction fails to find a match)
+ if (g.NavMoveSubmitted && g.NavId == 0)
+ {
+ IMGUI_DEBUG_LOG_NAV("[nav] NavInitRequest: from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
+ g.NavInitRequest = g.NavInitRequestFromMove = true;
+ g.NavInitResultId = 0;
+ g.NavDisableHighlight = false;
+ }
+
+ // When using gamepad, we project the reference nav bounding box into window visible area.
+ // This is to allow resuming navigation inside the visible area after doing a large amount of scrolling, since with gamepad every movements are relative
+ // (can't focus a visible object like we can with the mouse).
+ if (g.NavMoveSubmitted && g.NavInputSource == ImGuiInputSource_Gamepad && g.NavLayer == ImGuiNavLayer_Main && window != NULL)
+ {
+ ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1));
+ if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
+ {
+ IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: clamp NavRectRel\n");
+ float pad = window->CalcFontSize() * 0.5f;
+ window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
+ window->NavRectRel[g.NavLayer].ClipWithFull(window_rect_rel);
+ g.NavId = g.NavFocusScopeId = 0;
+ }
+ }
+
+ // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
+ ImRect scoring_rect;
+ if (window != NULL)
+ {
+ ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0);
+ scoring_rect = ImRect(window->Pos + nav_rect_rel.Min, window->Pos + nav_rect_rel.Max);
+ scoring_rect.TranslateY(scoring_rect_offset_y);
+ scoring_rect.Min.x = ImMin(scoring_rect.Min.x + 1.0f, scoring_rect.Max.x);
+ scoring_rect.Max.x = scoring_rect.Min.x;
+ IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
+ //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG]
+ }
+ g.NavScoringRect = scoring_rect;
+}
+
+// Apply result from previous frame navigation directional move request. Always called from NavUpdate()
+void ImGui::NavMoveRequestApplyResult()
+{
+ ImGuiContext& g = *GImGui;
+#if IMGUI_DEBUG_NAV_SCORING
+ if (g.NavMoveFlags & ImGuiNavMoveFlags_DebugNoResult) // [DEBUG] Scoring all items in NavWindow at all times
+ return;
+#endif
+
+ // Select which result to use
+ ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL;
+
+ // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
+ if (result == NULL)
{
- // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
if (g.NavId != 0)
{
g.NavDisableHighlight = false;
@@ -9395,13 +9521,10 @@ static void ImGui::NavUpdateMoveResult()
return;
}
- // Select which result to use
- ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
-
// PageUp/PageDown behavior first jumps to the bottom/top mostly visible item, _otherwise_ use the result from the previous/next page.
- if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet)
- if (g.NavMoveResultLocalVisibleSet.ID != 0 && g.NavMoveResultLocalVisibleSet.ID != g.NavId)
- result = &g.NavMoveResultLocalVisibleSet;
+ if (g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet)
+ if (g.NavMoveResultLocalVisible.ID != 0 && g.NavMoveResultLocalVisible.ID != g.NavId)
+ result = &g.NavMoveResultLocalVisible;
// Maybe entering a flattened child from the outside? In this case solve the tie using the regular scoring rules.
if (result != &g.NavMoveResultOther && g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow)
@@ -9413,7 +9536,7 @@ static void ImGui::NavUpdateMoveResult()
if (g.NavLayer == ImGuiNavLayer_Main)
{
ImVec2 delta_scroll;
- if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_ScrollToEdge)
+ if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdge)
{
float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
delta_scroll.y = result->Window->Scroll.y - scroll_target;
@@ -9437,84 +9560,137 @@ static void ImGui::NavUpdateMoveResult()
// Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
g.NavJustMovedToId = result->ID;
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
- g.NavJustMovedToKeyMods = g.NavMoveRequestKeyMods;
+ g.NavJustMovedToKeyMods = g.NavMoveKeyMods;
}
+
+ // Focus
IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequest: result NavID 0x%08X in Layer %d Window \"%s\"\n", result->ID, g.NavLayer, g.NavWindow->Name);
SetNavID(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
+
+ // Enable nav highlight
g.NavDisableHighlight = false;
g.NavDisableMouseHover = g.NavMousePosDirty = true;
}
+// Process NavCancel input (to close a popup, get back to parent, clear focus)
+// FIXME: In order to support e.g. Escape to clear a selection we'll need:
+// - either to store the equivalent of ActiveIdUsingKeyInputMask for a FocusScope and test for it.
+// - either to move most/all of those tests to the epilogue/end functions of the scope they are dealing with (e.g. exit child window in EndChild()) or in EndFrame(), to allow an earlier intercept
+static void ImGui::NavUpdateCancelRequest()
+{
+ ImGuiContext& g = *GImGui;
+ if (!IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed))
+ return;
+
+ IMGUI_DEBUG_LOG_NAV("[nav] ImGuiNavInput_Cancel\n");
+ if (g.ActiveId != 0)
+ {
+ if (!IsActiveIdUsingNavInput(ImGuiNavInput_Cancel))
+ ClearActiveID();
+ }
+ else if (g.NavLayer != ImGuiNavLayer_Main)
+ {
+ // Leave the "menu" layer
+ NavRestoreLayer(ImGuiNavLayer_Main);
+ }
+ else if (g.NavWindow && g.NavWindow != g.NavWindow->RootWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
+ {
+ // Exit child window
+ ImGuiWindow* child_window = g.NavWindow;
+ ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
+ IM_ASSERT(child_window->ChildId != 0);
+ ImRect child_rect = child_window->Rect();
+ FocusWindow(parent_window);
+ SetNavID(child_window->ChildId, ImGuiNavLayer_Main, 0, ImRect(child_rect.Min - parent_window->Pos, child_rect.Max - parent_window->Pos));
+ }
+ else if (g.OpenPopupStack.Size > 0)
+ {
+ // Close open popup/menu
+ if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
+ ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
+ }
+ else
+ {
+ // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
+ if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
+ g.NavWindow->NavLastIds[0] = 0;
+ g.NavId = g.NavFocusScopeId = 0;
+ }
+}
+
// Handle PageUp/PageDown/Home/End keys
+// Called from NavUpdateCreateMoveRequest() which will use our output to create a move request
+// FIXME-NAV: This doesn't work properly with NavFlattened siblings as we use NavWindow rectangle for reference
+// FIXME-NAV: how to get Home/End to aim at the beginning/end of a 2D grid?
static float ImGui::NavUpdatePageUpPageDown()
{
ImGuiContext& g = *GImGui;
ImGuiIO& io = g.IO;
- if (g.NavMoveDir != ImGuiDir_None || g.NavWindow == NULL)
- return 0.0f;
- if ((g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL || g.NavLayer != ImGuiNavLayer_Main)
+ ImGuiWindow* window = g.NavWindow;
+ if ((window->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL || g.NavLayer != ImGuiNavLayer_Main)
return 0.0f;
- ImGuiWindow* window = g.NavWindow;
const bool page_up_held = IsKeyDown(io.KeyMap[ImGuiKey_PageUp]) && !IsActiveIdUsingKey(ImGuiKey_PageUp);
const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown);
const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home);
const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End);
- if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed
+ if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out
+ return 0.0f;
+
+ if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
{
- if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
+ // Fallback manual-scroll when window has no navigable item
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
+ SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
+ SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
+ else if (home_pressed)
+ SetScrollY(window, 0.0f);
+ else if (end_pressed)
+ SetScrollY(window, window->ScrollMax.y);
+ }
+ else
+ {
+ ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
+ const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
+ float nav_scoring_rect_offset_y = 0.0f;
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
{
- // Fallback manual-scroll when window has no navigable item
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
- SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
- else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
- SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
- else if (home_pressed)
- SetScrollY(window, 0.0f);
- else if (end_pressed)
- SetScrollY(window, window->ScrollMax.y);
+ nav_scoring_rect_offset_y = -page_offset_y;
+ g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
+ g.NavMoveClipDir = ImGuiDir_Up;
+ g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
}
- else
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
{
- ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
- const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
- float nav_scoring_rect_offset_y = 0.0f;
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
- {
- nav_scoring_rect_offset_y = -page_offset_y;
- g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
- g.NavMoveClipDir = ImGuiDir_Up;
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
- }
- else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
- {
- nav_scoring_rect_offset_y = +page_offset_y;
- g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
- g.NavMoveClipDir = ImGuiDir_Down;
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
- }
- else if (home_pressed)
- {
- // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
- // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
- // Preserve current horizontal position if we have any.
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
- if (nav_rect_rel.IsInverted())
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
- g.NavMoveDir = ImGuiDir_Down;
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
- }
- else if (end_pressed)
- {
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
- if (nav_rect_rel.IsInverted())
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
- g.NavMoveDir = ImGuiDir_Up;
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
- }
- return nav_scoring_rect_offset_y;
+ nav_scoring_rect_offset_y = +page_offset_y;
+ g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
+ g.NavMoveClipDir = ImGuiDir_Down;
+ g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
}
+ else if (home_pressed)
+ {
+ // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
+ // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
+ // Preserve current horizontal position if we have any.
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
+ if (nav_rect_rel.IsInverted())
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
+ g.NavMoveDir = ImGuiDir_Down;
+ g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
+ // FIXME-NAV: MoveClipDir left to _None, intentional?
+ }
+ else if (end_pressed)
+ {
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
+ if (nav_rect_rel.IsInverted())
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
+ g.NavMoveDir = ImGuiDir_Up;
+ g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
+ // FIXME-NAV: MoveClipDir left to _None, intentional?
+ }
+ return nav_scoring_rect_offset_y;
}
return 0.0f;
}
@@ -9528,13 +9704,14 @@ static void ImGui::NavEndFrame()
NavUpdateWindowingOverlay();
// Perform wrap-around in menus
- ImGuiWindow* window = g.NavWrapRequestWindow;
- ImGuiNavMoveFlags move_flags = g.NavWrapRequestFlags;
- if (window != NULL && g.NavWindow == window && NavMoveRequestButNoResultYet() && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == ImGuiNavLayer_Main)
+ // FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame.
+ ImGuiWindow* window = g.NavWindow;
+ const ImGuiNavMoveFlags move_flags = g.NavMoveFlags;
+ const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY;
+ if (window && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
{
- IM_ASSERT(move_flags != 0); // No points calling this with no wrapping
- ImRect bb_rel = window->NavRectRel[0];
-
+ bool do_forward = false;
+ ImRect bb_rel = window->NavRectRel[g.NavLayer];
ImGuiDir clip_dir = g.NavMoveDir;
if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
{
@@ -9545,7 +9722,7 @@ static void ImGui::NavEndFrame()
bb_rel.TranslateY(-bb_rel.GetHeight());
clip_dir = ImGuiDir_Up;
}
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
+ do_forward = true;
}
if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
{
@@ -9555,7 +9732,7 @@ static void ImGui::NavEndFrame()
bb_rel.TranslateY(+bb_rel.GetHeight());
clip_dir = ImGuiDir_Down;
}
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
+ do_forward = true;
}
if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
{
@@ -9566,7 +9743,7 @@ static void ImGui::NavEndFrame()
bb_rel.TranslateX(-bb_rel.GetWidth());
clip_dir = ImGuiDir_Left;
}
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
+ do_forward = true;
}
if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
{
@@ -9576,7 +9753,12 @@ static void ImGui::NavEndFrame()
bb_rel.TranslateX(+bb_rel.GetWidth());
clip_dir = ImGuiDir_Right;
}
- NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
+ do_forward = true;
+ }
+ if (do_forward)
+ {
+ window->NavRectRel[g.NavLayer] = bb_rel;
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags);
}
}
}
@@ -9621,6 +9803,8 @@ static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
static void ImGui::NavUpdateWindowing()
{
ImGuiContext& g = *GImGui;
+ ImGuiIO& io = g.IO;
+
ImGuiWindow* apply_focus_window = NULL;
bool apply_toggle_layer = false;
@@ -9632,25 +9816,26 @@ static void ImGui::NavUpdateWindowing()
// Fade out
if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL)
{
- g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - g.IO.DeltaTime * 10.0f, 0.0f);
+ g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - io.DeltaTime * 10.0f, 0.0f);
if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f)
g.NavWindowingTargetAnim = NULL;
}
// Start CTRL-TAB or Square+L/R window selection
- bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
- bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
+ const bool nav_keyboard_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
+ const bool start_windowing_with_gamepad = allow_windowing && !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
+ const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && nav_keyboard_active && io.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab);
if (start_windowing_with_gamepad || start_windowing_with_keyboard)
if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
{
g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow;
g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
- g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true;
+ g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer
g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad;
}
// Gamepad update
- g.NavWindowingTimer += g.IO.DeltaTime;
+ g.NavWindowingTimer += io.DeltaTime;
if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_Gamepad)
{
// Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise
@@ -9682,31 +9867,49 @@ static void ImGui::NavUpdateWindowing()
// Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise
g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
if (IsKeyPressedMap(ImGuiKey_Tab, true))
- NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1);
- if (!g.IO.KeyCtrl)
+ NavUpdateWindowingHighlightWindow(io.KeyShift ? +1 : -1);
+ if (!io.KeyCtrl)
apply_focus_window = g.NavWindowingTarget;
}
// Keyboard: Press and Release ALT to toggle menu layer
- // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of backend clearing releases all keys on ALT-TAB
- if (IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Pressed))
+ // - Testing that only Alt is tested prevents Alt+Shift or AltGR from toggling menu layer.
+ // - AltGR is normally Alt+Ctrl but we can't reliably detect it (not all backends/systems/layout emit it as Alt+Ctrl). But even on keyboards without AltGR we don't want Alt+Ctrl to open menu anyway.
+ if (nav_keyboard_active && io.KeyMods == ImGuiKeyModFlags_Alt && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) == 0)
+ {
g.NavWindowingToggleLayer = true;
- if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
- if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
- apply_toggle_layer = true;
+ g.NavInputSource = ImGuiInputSource_Keyboard;
+ }
+ if (g.NavWindowingToggleLayer && g.NavInputSource == ImGuiInputSource_Keyboard)
+ {
+ // We cancel toggling nav layer when any text has been typed (generally while holding Alt). (See #370)
+ // We cancel toggling nav layer when other modifiers are pressed. (See #4439)
+ if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper)
+ g.NavWindowingToggleLayer = false;
+
+ // Apply layer toggle on release
+ // Important: we don't assume that Alt was previously held in order to handle loss of focus when backend calls io.AddFocusEvent(false)
+ // Important: as before version <18314 we lacked an explicit IO event for focus gain/loss, we also compare mouse validity to detect old backends clearing mouse pos on focus loss.
+ if (!(io.KeyMods & ImGuiKeyModFlags_Alt) && (io.KeyModsPrev & ImGuiKeyModFlags_Alt) && g.NavWindowingToggleLayer)
+ if (g.ActiveId == 0 || g.ActiveIdAllowOverlap)
+ if (IsMousePosValid(&io.MousePos) == IsMousePosValid(&io.MousePosPrev))
+ apply_toggle_layer = true;
+ if (!io.KeyAlt)
+ g.NavWindowingToggleLayer = false;
+ }
// Move window
if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
{
ImVec2 move_delta;
- if (g.NavInputSource == ImGuiInputSource_Keyboard && !g.IO.KeyShift)
+ if (g.NavInputSource == ImGuiInputSource_Keyboard && !io.KeyShift)
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down);
if (g.NavInputSource == ImGuiInputSource_Gamepad)
move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down);
if (move_delta.x != 0.0f || move_delta.y != 0.0f)
{
const float NAV_MOVE_SPEED = 800.0f;
- const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
+ const float move_speed = ImFloor(NAV_MOVE_SPEED * io.DeltaTime * ImMin(io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y)); // FIXME: Doesn't handle variable framerate very well
ImGuiWindow* moving_window = g.NavWindowingTarget->RootWindow;
SetWindowPos(moving_window, moving_window->Pos + move_delta * move_speed, ImGuiCond_Always);
MarkIniSettingsDirty(moving_window);
@@ -9757,14 +9960,16 @@ static void ImGui::NavUpdateWindowing()
FocusWindow(new_nav_window);
new_nav_window->NavLastChildNavWindow = old_nav_window;
}
- g.NavDisableHighlight = false;
- g.NavDisableMouseHover = true;
- // Reinitialize navigation when entering menu bar with the Alt key.
+ // Toggle layer
const ImGuiNavLayer new_nav_layer = (g.NavWindow->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main;
- if (new_nav_layer == ImGuiNavLayer_Menu)
- g.NavWindow->NavLastIds[new_nav_layer] = 0;
- NavRestoreLayer(new_nav_layer);
+ if (new_nav_layer != g.NavLayer)
+ {
+ // Reinitialize navigation when entering menu bar with the Alt key (FIXME: could be a properly of the layer?)
+ if (new_nav_layer == ImGuiNavLayer_Menu)
+ g.NavWindow->NavLastIds[new_nav_layer] = 0;
+ NavRestoreLayer(new_nav_layer);
+ }
}
}
@@ -9857,14 +10062,16 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
return false;
if (g.ActiveIdMouseButton != -1)
mouse_button = g.ActiveIdMouseButton;
- if (g.IO.MouseDown[mouse_button] == false)
+ if (g.IO.MouseDown[mouse_button] == false || window->SkipItems)
return false;
g.ActiveIdAllowOverlap = false;
}
else
{
// Uncommon path: items without ID
- if (g.IO.MouseDown[mouse_button] == false)
+ if (g.IO.MouseDown[mouse_button] == false || window->SkipItems)
+ return false;
+ if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window))
return false;
// If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to:
@@ -9875,10 +10082,6 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
return false;
}
- // Early out
- if ((g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window))
- return false;
-
// Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image()
// We build a throwaway ID based on current ID stack + relative AABB of items in window.
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
@@ -9935,7 +10138,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
{
ImGuiWindow* tooltip_window = g.CurrentWindow;
- tooltip_window->SkipItems = true;
+ tooltip_window->Hidden = tooltip_window->SkipItems = true;
tooltip_window->HiddenFramesCanSkipItems = 1;
}
}
@@ -10044,7 +10247,7 @@ bool ImGui::BeginDragDropTarget()
if (!(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HoveredRect))
return false;
ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow;
- if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow)
+ if (hovered_window == NULL || window->RootWindow != hovered_window->RootWindow || window->SkipItems)
return false;
const ImRect& display_rect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? g.LastItemData.DisplayRect : g.LastItemData.Rect;
@@ -11273,7 +11476,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer);
Text("NavInputSource: %s", input_source_names[g.NavInputSource]);
Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
- Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId);
+ Text("NavActivateId/DownId/PressedId/InputId: %08X/%08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId, g.NavActivatePressedId, g.NavActivateInputId);
+ Text("NavActivateFlags: %04X", g.NavActivateFlags);
Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId);
Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL");
@@ -11472,16 +11676,17 @@ void ImGui::DebugNodeDrawList(ImGuiWindow* window, const ImDrawList* draw_list,
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb)
{
IM_ASSERT(show_mesh || show_aabb);
- ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
- ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset;
// Draw wire-frame version of all triangles
ImRect clip_rect = draw_cmd->ClipRect;
ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
ImDrawListFlags backup_flags = out_draw_list->Flags;
out_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
- for (unsigned int idx_n = draw_cmd->IdxOffset; idx_n < draw_cmd->IdxOffset + draw_cmd->ElemCount; )
+ for (unsigned int idx_n = draw_cmd->IdxOffset, idx_end = draw_cmd->IdxOffset + draw_cmd->ElemCount; idx_n < idx_end; )
{
+ ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; // We don't hold on those pointers past iterations as ->AddPolyline() may invalidate them if out_draw_list==draw_list
+ ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset;
+
ImVec2 triangle[3];
for (int n = 0; n < 3; n++, idx_n++)
vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos));
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui.h b/3rdparty/bgfx/3rdparty/dear-imgui/imgui.h
index 84e8a6b7253..f679762e5ae 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui.h
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui.h
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (headers)
// Help:
@@ -11,11 +11,14 @@
// - FAQ http://dearimgui.org/faq
// - Homepage & latest https://github.com/ocornut/imgui
// - Releases & changelog https://github.com/ocornut/imgui/releases
-// - Gallery https://github.com/ocornut/imgui/issues/3793 (please post your screenshots/video there!)
+// - Gallery https://github.com/ocornut/imgui/issues/4451 (please post your screenshots/video there!)
// - Wiki https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Issues & support https://github.com/ocornut/imgui/issues
-// - Discussions https://github.com/ocornut/imgui/discussions
+
+// Getting Started?
+// - For first-time users having issues compiling/linking/running or issues loading fonts:
+// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
/*
@@ -60,8 +63,8 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
-#define IMGUI_VERSION "1.84 WIP"
-#define IMGUI_VERSION_NUM 18312
+#define IMGUI_VERSION "1.85 WIP"
+#define IMGUI_VERSION_NUM 18417
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
@@ -160,7 +163,7 @@ struct ImGuiTextBuffer; // Helper to hold and append into a text buf
struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]")
struct ImGuiViewport; // A Platform Window (always only one in 'master' branch), in the future may represent Platform Monitor
-// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file)
+// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags without overhead, and to not pollute the top of this file)
// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists!
// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments.
@@ -200,27 +203,22 @@ typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: f
typedef int ImGuiViewportFlags; // -> enum ImGuiViewportFlags_ // Flags: for ImGuiViewport
typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild()
-// Other types
-#ifndef ImTextureID // ImTextureID [configurable type: override in imconfig.h with '#define ImTextureID xxx']
-typedef void* ImTextureID; // User data for rendering backend to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details.
+// ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type]
+// - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file.
+// - This can be whatever to you want it to be! read the FAQ about ImTextureID for details.
+#ifndef ImTextureID
+typedef void* ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that)
#endif
-typedef unsigned int ImGuiID; // A unique ID used by widgets, typically hashed from a stack of string.
-typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); // Callback function for ImGui::InputText()
-typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); // Callback function for ImGui::SetNextWindowSizeConstraints()
-typedef void* (*ImGuiMemAllocFunc)(size_t sz, void* user_data); // Function signature for ImGui::SetAllocatorFunctions()
-typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data); // Function signature for ImGui::SetAllocatorFunctions()
-// Character types
-// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
-typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings.
-typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
-#ifdef IMGUI_USE_WCHAR32 // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16]
-typedef ImWchar32 ImWchar;
-#else
-typedef ImWchar16 ImWchar;
+// ImDrawIdx: vertex index. [Compile-time configurable type]
+// - To use 16-bit indices + allow large meshes: backend need to set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset (recommended).
+// - To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in your imconfig.h file.
+#ifndef ImDrawIdx
+typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends)
#endif
-// Basic scalar data types
+// Scalar data types
+typedef unsigned int ImGuiID;// A unique ID used by widgets (typically the result of hashing a stack of string)
typedef signed char ImS8; // 8-bit signed integer
typedef unsigned char ImU8; // 8-bit unsigned integer
typedef signed short ImS16; // 16-bit signed integer
@@ -239,7 +237,24 @@ typedef signed long long ImS64; // 64-bit signed integer (post C++11)
typedef unsigned long long ImU64; // 64-bit unsigned integer (post C++11)
#endif
-// 2D vector (often used to store positions or sizes)
+// Character types
+// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display)
+typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings.
+typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings.
+#ifdef IMGUI_USE_WCHAR32 // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16]
+typedef ImWchar32 ImWchar;
+#else
+typedef ImWchar16 ImWchar;
+#endif
+
+// Callback and functions types
+typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData* data); // Callback function for ImGui::InputText()
+typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); // Callback function for ImGui::SetNextWindowSizeConstraints()
+typedef void* (*ImGuiMemAllocFunc)(size_t sz, void* user_data); // Function signature for ImGui::SetAllocatorFunctions()
+typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data); // Function signature for ImGui::SetAllocatorFunctions()
+
+// ImVec2: 2D vector used to store positions, sizes etc. [Compile-time configurable type]
+// This is a frequently used type in the API. Consider using IM_VEC2_CLASS_EXTRA to create implicit cast from/to our preferred type.
IM_MSVC_RUNTIME_CHECKS_OFF
struct ImVec2
{
@@ -253,7 +268,7 @@ struct ImVec2
#endif
};
-// 4D vector (often used to store floating-point colors)
+// ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type]
struct ImVec4
{
float x, y, z, w;
@@ -367,9 +382,8 @@ namespace ImGui
// - Those functions are bound to be redesigned (they are confusing, incomplete and the Min/Max return values are in local window coordinates which increases confusion)
IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
- IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates
- IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates
- IMGUI_API float GetWindowContentRegionWidth(); //
+ IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min for the full window (roughly (0,0)-Scroll), in window coordinates
+ IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max for the full window (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates
// Windows Scrolling
IMGUI_API float GetScrollX(); // get scrolling amount [0 .. GetScrollMaxX()]
@@ -508,12 +522,12 @@ namespace ImGui
IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1);
// Widgets: Drag Sliders
- // - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped and can go off-bounds.
+ // - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
- // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits.
+ // - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used.
// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.
// - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
// - Legacy: Pre-1.78 there are DragXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
@@ -532,7 +546,7 @@ namespace ImGui
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
// Widgets: Regular Sliders
- // - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped and can go off-bounds.
+ // - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
// - Legacy: Pre-1.78 there are SliderXXX() function signatures that takes a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
@@ -618,7 +632,7 @@ namespace ImGui
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1);
// Widgets: Data Plotting
- // - Consider using ImPlot (https://github.com/epezent/implot)
+ // - Consider using ImPlot (https://github.com/epezent/implot) which is much better!
IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
IMGUI_API void PlotLines(const char* label, float(*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0));
IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float));
@@ -799,6 +813,13 @@ namespace ImGui
IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true!
IMGUI_API const ImGuiPayload* GetDragDropPayload(); // peek directly into the current payload from anywhere. may return NULL. use ImGuiPayload::IsDataType() to test for the payload type.
+ // Disabling [BETA API]
+ // - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
+ // - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
+ // - BeginDisabled(false) essentially does nothing useful but is provided to facilitate use of boolean expressions. If you can avoid calling BeginDisabled(False)/EndDisabled() best to avoid it.
+ IMGUI_API void BeginDisabled(bool disabled = true);
+ IMGUI_API void EndDisabled();
+
// Clipping
// - Mouse hovering is affected by ImGui::PushClipRect() calls, unlike direct calls to ImDrawList::PushClipRect() which are render only.
IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect);
@@ -1243,9 +1264,11 @@ enum ImGuiTableBgTarget_
enum ImGuiFocusedFlags_
{
ImGuiFocusedFlags_None = 0,
- ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused
- ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy)
- ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use 'io.WantCaptureMouse' instead! Please read the FAQ!
+ ImGuiFocusedFlags_ChildWindows = 1 << 0, // Return true if any children of the window is focused
+ ImGuiFocusedFlags_RootWindow = 1 << 1, // Test from root window (top most parent of the current hierarchy)
+ ImGuiFocusedFlags_AnyWindow = 1 << 2, // Return true if any window is focused. Important: If you are trying to tell how to dispatch your low-level inputs, do NOT use this. Use 'io.WantCaptureMouse' instead! Please read the FAQ!
+ ImGuiFocusedFlags_NoPopupHierarchy = 1 << 3, // Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow)
+ //ImGuiFocusedFlags_DockHierarchy = 1 << 4, // Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow)
ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows
};
@@ -1258,11 +1281,13 @@ enum ImGuiHoveredFlags_
ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered
ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy)
ImGuiHoveredFlags_AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered
- ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window
- //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
- ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
- ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is obstructed or overlapped by another window
- ImGuiHoveredFlags_AllowWhenDisabled = 1 << 7, // Return true even if the item is disabled
+ ImGuiHoveredFlags_NoPopupHierarchy = 1 << 3, // IsWindowHovered() only: Do not consider popup hierarchy (do not treat popup emitter as parent of popup) (when used with _ChildWindows or _RootWindow)
+ //ImGuiHoveredFlags_DockHierarchy = 1 << 4, // IsWindowHovered() only: Consider docking hierarchy (treat dockspace host as parent of docked window) (when used with _ChildWindows or _RootWindow)
+ ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 5, // Return true even if a popup window is normally blocking access to this item/window
+ //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 6, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet.
+ ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 7, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns.
+ ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 8, // Return true even if the position is obstructed or overlapped by another window
+ ImGuiHoveredFlags_AllowWhenDisabled = 1 << 9, // Return true even if the item is disabled
ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped,
ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows
};
@@ -1388,13 +1413,12 @@ enum ImGuiNavInput_
// [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them.
// Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[].
- ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt
ImGuiNavInput_KeyLeft_, // move left // = Arrow keys
ImGuiNavInput_KeyRight_, // move right
ImGuiNavInput_KeyUp_, // move up
ImGuiNavInput_KeyDown_, // move down
ImGuiNavInput_COUNT,
- ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_
+ ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyLeft_
};
// Configuration flags stored in io.ConfigFlags. Set by user/application.
@@ -1493,6 +1517,7 @@ enum ImGuiStyleVar_
{
// Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions)
ImGuiStyleVar_Alpha, // float Alpha
+ ImGuiStyleVar_DisabledAlpha, // float DisabledAlpha
ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding
ImGuiStyleVar_WindowRounding, // float WindowRounding
ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize
@@ -1739,6 +1764,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
struct ImGuiStyle
{
float Alpha; // Global alpha applies to everything in Dear ImGui.
+ float DisabledAlpha; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
ImVec2 WindowPadding; // Padding within a window.
float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly).
@@ -1868,7 +1894,9 @@ struct ImGuiIO
IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input
IMGUI_API void AddInputCharacterUTF16(ImWchar16 c); // Queue new character input from an UTF-16 character, it can be a surrogate
IMGUI_API void AddInputCharactersUTF8(const char* str); // Queue new characters input from an UTF-8 string
- IMGUI_API void ClearInputCharacters(); // Clear the text input buffer manually
+ IMGUI_API void AddFocusEvent(bool focused); // Notifies Dear ImGui when hosting platform windows lose or gain input focus
+ IMGUI_API void ClearInputCharacters(); // [Internal] Clear the text input buffer manually
+ IMGUI_API void ClearInputKeys(); // [Internal] Release all keys
//------------------------------------------------------------------
// Output - Updated by NewFrame() or EndFrame()/Render()
@@ -1895,14 +1923,17 @@ struct ImGuiIO
// [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed!
//------------------------------------------------------------------
+ bool WantCaptureMouseUnlessPopupClose;// Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
ImGuiKeyModFlags KeyMods; // Key mods flags (same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags), updated by NewFrame()
+ ImGuiKeyModFlags KeyModsPrev; // Previous key mods
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
ImVec2 MouseClickedPos[5]; // Position at time of clicking
double MouseClickedTime[5]; // Time of last click (used to figure out double-click)
bool MouseClicked[5]; // Mouse button went from !Down to Down
bool MouseDoubleClicked[5]; // Has mouse button been double-clicked?
bool MouseReleased[5]; // Mouse button went from Down to !Down
- bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window. We don't request mouse capture from the application if click started outside ImGui bounds.
+ bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
+ bool MouseDownOwnedUnlessPopupClose[5];//Track if button was clicked inside a dear imgui window.
bool MouseDownWasDoubleClick[5]; // Track if button down was a double-click
float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)
float MouseDownDurationPrev[5]; // Previous time the mouse button has been down
@@ -1913,6 +1944,7 @@ struct ImGuiIO
float NavInputsDownDuration[ImGuiNavInput_COUNT];
float NavInputsDownDurationPrev[ImGuiNavInput_COUNT];
float PenPressure; // Touch/Pen pressure (0.0f to 1.0f, should be >0.0f only when MouseDown[0] == true). Helper storage currently unused by Dear ImGui.
+ bool AppFocusLost;
ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16
ImVector<ImWchar> InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper.
@@ -2267,13 +2299,6 @@ struct ImDrawCmd
inline ImTextureID GetTexID() const { return TextureId; }
};
-// Vertex index, default to 16-bit
-// To allow large meshes with 16-bit indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer backend (recommended).
-// To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in imconfig.h.
-#ifndef ImDrawIdx
-typedef unsigned short ImDrawIdx;
-#endif
-
// Vertex layout
#ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT
struct ImDrawVert
@@ -2802,6 +2827,8 @@ struct ImGuiViewport
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
namespace ImGui
{
+ // OBSOLETED in 1.85 (from August 2021)
+ static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; }
// OBSOLETED in 1.81 (from February 2021)
IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // Helper to calculate size from items_count and height_in_items
static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); }
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp
index 715c84cc474..febca565f28 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (demo code)
// Help:
@@ -379,6 +379,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::MenuItem("Documents", NULL, &show_app_documents);
ImGui::EndMenu();
}
+ //if (ImGui::MenuItem("MenuItem")) {} // You can also use MenuItem() inside a menu bar!
if (ImGui::BeginMenu("Tools"))
{
ImGui::MenuItem("Metrics/Debugger", NULL, &show_app_metrics);
@@ -458,7 +459,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
{
HelpMarker(
"Those flags are set by the backends (imgui_impl_xxx files) to specify their capabilities.\n"
- "Here we expose then as read-only fields to avoid breaking interactions with your backend.");
+ "Here we expose them as read-only fields to avoid breaking interactions with your backend.");
// Make a local copy to avoid modifying actual backend flags.
ImGuiBackendFlags backend_flags = io.BackendFlags;
@@ -533,6 +534,10 @@ static void ShowDemoWindowWidgets()
if (!ImGui::CollapsingHeader("Widgets"))
return;
+ static bool disable_all = false; // The Checkbox for that is inside the "Disabled" section at the bottom
+ if (disable_all)
+ ImGui::BeginDisabled();
+
if (ImGui::TreeNode("Basic"))
{
static int clicked = 0;
@@ -1557,16 +1562,17 @@ static void ShowDemoWindowWidgets()
}
// Plot/Graph widgets are not very good.
- // Consider writing your own, or using a third-party one, see:
- // - ImPlot https://github.com/epezent/implot
- // - others https://github.com/ocornut/imgui/wiki/Useful-Extensions
+ // Consider using a third-party library such as ImPlot: https://github.com/epezent/implot
+ // (see others https://github.com/ocornut/imgui/wiki/Useful-Extensions)
if (ImGui::TreeNode("Plots Widgets"))
{
static bool animate = true;
ImGui::Checkbox("Animate", &animate);
+ // Plot as lines and plot as histogram
static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f };
ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr));
+ ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f));
// Fill an array of contiguous float values to plot
// Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float
@@ -1596,7 +1602,6 @@ static void ShowDemoWindowWidgets()
sprintf(overlay, "avg %f", average);
ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, overlay, -1.0f, 1.0f, ImVec2(0, 80.0f));
}
- ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f));
// Use functions to generate output
// FIXME: This is rather awkward because current plot API only pass in indices.
@@ -2181,7 +2186,7 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
- if (ImGui::TreeNode("Querying Status (Edited/Active/Focused/Hovered etc.)"))
+ if (ImGui::TreeNode("Querying Item Status (Edited/Active/Hovered etc.)"))
{
// Select an item type
const char* item_names[] =
@@ -2189,16 +2194,20 @@ static void ShowDemoWindowWidgets()
"Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputFloat",
"InputFloat3", "ColorEdit4", "Selectable", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox"
};
- static int item_type = 1;
+ static int item_type = 4;
+ static bool item_disabled = false;
ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names));
ImGui::SameLine();
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered().");
+ ImGui::Checkbox("Item Disabled", &item_disabled);
// Submit selected item item so we can query their status in the code following it.
bool ret = false;
static bool b = false;
static float col4f[4] = { 1.0f, 0.5, 0.0f, 1.0f };
static char str[16] = {};
+ if (item_disabled)
+ ImGui::BeginDisabled(true);
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
if (item_type == 2) { ImGui::PushButtonRepeat(true); ret = ImGui::Button("ITEM: Button"); ImGui::PopButtonRepeat(); } // Testing button (with repeater)
@@ -2226,6 +2235,7 @@ static void ShowDemoWindowWidgets()
"IsItemHovered(_AllowWhenBlockedByPopup) = %d\n"
"IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n"
"IsItemHovered(_AllowWhenOverlapped) = %d\n"
+ "IsItemHovered(_AllowWhenDisabled) = %d\n"
"IsItemHovered(_RectOnly) = %d\n"
"IsItemActive() = %d\n"
"IsItemEdited() = %d\n"
@@ -2244,6 +2254,7 @@ static void ShowDemoWindowWidgets()
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped),
+ ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled),
ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly),
ImGui::IsItemActive(),
ImGui::IsItemEdited(),
@@ -2258,43 +2269,66 @@ static void ShowDemoWindowWidgets()
ImGui::GetItemRectSize().x, ImGui::GetItemRectSize().y
);
+ if (item_disabled)
+ ImGui::EndDisabled();
+
+ char buf[1] = "";
+ ImGui::InputText("unused", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_ReadOnly);
+ ImGui::SameLine();
+ HelpMarker("This widget is only here to be able to tab-out of the widgets above and see e.g. Deactivated() status.");
+
+ ImGui::TreePop();
+ }
+
+ if (ImGui::TreeNode("Querying Window Status (Focused/Hovered etc.)"))
+ {
static bool embed_all_inside_a_child_window = false;
- ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window);
+ ImGui::Checkbox("Embed everything inside a child window for testing _RootWindow flag.", &embed_all_inside_a_child_window);
if (embed_all_inside_a_child_window)
ImGui::BeginChild("outer_child", ImVec2(0, ImGui::GetFontSize() * 20.0f), true);
// Testing IsWindowFocused() function with its various flags.
- // Note that the ImGuiFocusedFlags_XXX flags can be combined.
ImGui::BulletText(
"IsWindowFocused() = %d\n"
"IsWindowFocused(_ChildWindows) = %d\n"
+ "IsWindowFocused(_ChildWindows|_NoPopupHierarchy) = %d\n"
"IsWindowFocused(_ChildWindows|_RootWindow) = %d\n"
+ "IsWindowFocused(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n"
"IsWindowFocused(_RootWindow) = %d\n"
+ "IsWindowFocused(_RootWindow|_NoPopupHierarchy) = %d\n"
"IsWindowFocused(_AnyWindow) = %d\n",
ImGui::IsWindowFocused(),
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows),
+ ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_NoPopupHierarchy),
ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow),
+ ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy),
ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow),
+ ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_NoPopupHierarchy),
ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow));
// Testing IsWindowHovered() function with its various flags.
- // Note that the ImGuiHoveredFlags_XXX flags can be combined.
ImGui::BulletText(
"IsWindowHovered() = %d\n"
"IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n"
"IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n"
"IsWindowHovered(_ChildWindows) = %d\n"
+ "IsWindowHovered(_ChildWindows|_NoPopupHierarchy) = %d\n"
"IsWindowHovered(_ChildWindows|_RootWindow) = %d\n"
- "IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
+ "IsWindowHovered(_ChildWindows|_RootWindow|_NoPopupHierarchy) = %d\n"
"IsWindowHovered(_RootWindow) = %d\n"
+ "IsWindowHovered(_RootWindow|_NoPopupHierarchy) = %d\n"
+ "IsWindowHovered(_ChildWindows|_AllowWhenBlockedByPopup) = %d\n"
"IsWindowHovered(_AnyWindow) = %d\n",
ImGui::IsWindowHovered(),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem),
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows),
+ ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy),
ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow),
- ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
+ ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow),
+ ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_NoPopupHierarchy),
+ ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_AllowWhenBlockedByPopup),
ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow));
ImGui::BeginChild("child", ImVec2(0, 50), true);
@@ -2303,9 +2337,6 @@ static void ShowDemoWindowWidgets()
if (embed_all_inside_a_child_window)
ImGui::EndChild();
- static char unused_str[] = "This widget is only here to be able to tab-out of the widgets above.";
- ImGui::InputText("unused", unused_str, IM_ARRAYSIZE(unused_str), ImGuiInputTextFlags_ReadOnly);
-
// Calling IsItemHovered() after begin returns the hovered status of the title bar.
// This is useful in particular if you want to create a context menu associated to the title bar of a window.
static bool test_window = false;
@@ -2327,6 +2358,18 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
+
+ // Demonstrate BeginDisabled/EndDisabled using a checkbox located at the bottom of the section (which is a bit odd:
+ // logically we'd have this checkbox at the top of the section, but we don't want this feature to steal that space)
+ if (disable_all)
+ ImGui::EndDisabled();
+
+ if (ImGui::TreeNode("Disable block"))
+ {
+ ImGui::Checkbox("Disable entire section above", &disable_all);
+ ImGui::SameLine(); HelpMarker("Demonstrate using BeginDisabled()/EndDisabled() across this section.");
+ ImGui::TreePop();
+ }
}
static void ShowDemoWindowLayout()
@@ -2347,7 +2390,7 @@ static void ShowDemoWindowLayout()
ImGuiWindowFlags window_flags = ImGuiWindowFlags_HorizontalScrollbar;
if (disable_mouse_wheel)
window_flags |= ImGuiWindowFlags_NoScrollWithMouse;
- ImGui::BeginChild("ChildL", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 260), false, window_flags);
+ ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x * 0.5f, 260), false, window_flags);
for (int i = 0; i < 100; i++)
ImGui::Text("%04d: scrollable region", i);
ImGui::EndChild();
@@ -2396,7 +2439,7 @@ static void ShowDemoWindowLayout()
// You can also call SetNextWindowPos() to position the child window. The parent window will effectively
// layout from this position.
// - Using ImGui::GetItemRectMin/Max() to query the "item" state (because the child window is an item from
- // the POV of the parent window). See 'Demo->Querying Status (Active/Focused/Hovered etc.)' for details.
+ // the POV of the parent window). See 'Demo->Querying Status (Edited/Active/Hovered etc.)' for details.
{
static int offset_x = 0;
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
@@ -5456,6 +5499,7 @@ static void ShowDemoWindowMisc()
// Display ImGuiIO output flags
ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse);
+ ImGui::Text("WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose);
ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard);
ImGui::Text("WantTextInput: %d", io.WantTextInput);
ImGui::Text("WantSetMousePos: %d", io.WantSetMousePos);
@@ -6041,6 +6085,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
HelpMarker("When drawing circle primitives with \"num_segments == 0\" tesselation will be calculated automatically.");
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
+ ImGui::DragFloat("Disabled Alpha", &style.DisabledAlpha, 0.005f, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Additional alpha multiplier for disabled items (multiply over current value of Alpha).");
ImGui::PopItemWidth();
ImGui::EndTabItem();
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp
index 01373a9e9d6..0abc75f343a 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (drawing and font code)
/*
@@ -1479,24 +1479,22 @@ void ImDrawList::AddCircle(const ImVec2& center, float radius, ImU32 col, int nu
if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f)
return;
- // Obtain segment count
if (num_segments <= 0)
{
- // Automatic segment count
- num_segments = _CalcCircleAutoSegmentCount(radius);
+ // Use arc with automatic segment count
+ _PathArcToFastEx(center, radius - 0.5f, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0);
+ _Path.Size--;
}
else
{
// Explicit segment count (still clamp to avoid drawing insanely tessellated shapes)
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
- }
- // Because we are filling a closed shape we remove 1 from the count of segments/points
- const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
- if (num_segments == 12)
- PathArcToFast(center, radius - 0.5f, 0, 12 - 1);
- else
+ // Because we are filling a closed shape we remove 1 from the count of segments/points
+ const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
PathArcTo(center, radius - 0.5f, 0.0f, a_max, num_segments - 1);
+ }
+
PathStroke(col, ImDrawFlags_Closed, thickness);
}
@@ -1505,24 +1503,22 @@ void ImDrawList::AddCircleFilled(const ImVec2& center, float radius, ImU32 col,
if ((col & IM_COL32_A_MASK) == 0 || radius <= 0.0f)
return;
- // Obtain segment count
if (num_segments <= 0)
{
- // Automatic segment count
- num_segments = _CalcCircleAutoSegmentCount(radius);
+ // Use arc with automatic segment count
+ _PathArcToFastEx(center, radius, 0, IM_DRAWLIST_ARCFAST_SAMPLE_MAX, 0);
+ _Path.Size--;
}
else
{
// Explicit segment count (still clamp to avoid drawing insanely tessellated shapes)
num_segments = ImClamp(num_segments, 3, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX);
- }
- // Because we are filling a closed shape we remove 1 from the count of segments/points
- const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
- if (num_segments == 12)
- PathArcToFast(center, radius, 0, 12 - 1);
- else
+ // Because we are filling a closed shape we remove 1 from the count of segments/points
+ const float a_max = (IM_PI * 2.0f) * ((float)num_segments - 1.0f) / (float)num_segments;
PathArcTo(center, radius, 0.0f, a_max, num_segments - 1);
+ }
+
PathFillConvex(col);
}
@@ -2002,7 +1998,7 @@ void ImFontAtlas::ClearInputData()
ConfigData.clear();
CustomRects.clear();
PackIdMouseCursors = PackIdLines = -1;
- TexReady = false;
+ // Important: we leave TexReady untouched
}
void ImFontAtlas::ClearTexData()
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h
index 0e813ef31fd..2fa71314fc1 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (internal structures/api)
// You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
@@ -18,6 +18,7 @@ Index of this file:
// [SECTION] Generic helpers
// [SECTION] ImDrawList support
// [SECTION] Widgets support: flags, enums, data structures
+// [SECTION] Navigation support
// [SECTION] Columns support
// [SECTION] Multi-select support
// [SECTION] Docking support
@@ -82,6 +83,7 @@ Index of this file:
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
+#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn'
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
@@ -141,8 +143,8 @@ struct ImGuiWindowSettings; // Storage for a window .ini settings (we ke
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
+typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag()
-typedef int ImGuiItemAddFlags; // -> enum ImGuiItemAddFlags_ // Flags: for ItemAdd()
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
@@ -735,20 +737,13 @@ enum ImGuiItemFlags_
ImGuiItemFlags_None = 0,
ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav)
ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
- ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See PushDisabled()/PushDisabled(). See github.com/ocornut/imgui/issues/211
+ ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211
ImGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop)
ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items)
ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window
ImGuiItemFlags_MixedValue = 1 << 6, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets)
- ImGuiItemFlags_ReadOnly = 1 << 7 // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
-};
-
-// Flags for ItemAdd()
-// FIXME-NAV: _Focusable is _ALMOST_ what you would expect to be called '_TabStop' but because SetKeyboardFocusHere() works on items with no TabStop we distinguish Focusable from TabStop.
-enum ImGuiItemAddFlags_
-{
- ImGuiItemAddFlags_None = 0,
- ImGuiItemAddFlags_Focusable = 1 << 0 // FIXME-NAV: In current/legacy scheme, Focusable+TabStop support are opt-in by widgets. We will transition it toward being opt-out, so this flag is expected to eventually disappear.
+ ImGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
+ ImGuiItemFlags_Inputable = 1 << 8 // false // [WIP] Auto-activate item when focused. Currently only used and supported by a few items before it becomes a generic feature.
};
// Storage for LastItem data
@@ -756,7 +751,7 @@ enum ImGuiItemStatusFlags_
{
ImGuiItemStatusFlags_None = 0,
ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test)
- ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // window->DC.LastItemDisplayRect is valid
+ ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid
ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues.
ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
@@ -798,7 +793,7 @@ enum ImGuiButtonFlagsPrivate_
ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
- //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use PushDisabled() or ImGuiItemFlags_Disabled
+ //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled
ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine
ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only)
@@ -914,49 +909,6 @@ enum ImGuiInputReadMode
ImGuiInputReadMode_RepeatFast
};
-enum ImGuiNavHighlightFlags_
-{
- ImGuiNavHighlightFlags_None = 0,
- ImGuiNavHighlightFlags_TypeDefault = 1 << 0,
- ImGuiNavHighlightFlags_TypeThin = 1 << 1,
- ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse.
- ImGuiNavHighlightFlags_NoRounding = 1 << 3
-};
-
-enum ImGuiNavDirSourceFlags_
-{
- ImGuiNavDirSourceFlags_None = 0,
- ImGuiNavDirSourceFlags_Keyboard = 1 << 0,
- ImGuiNavDirSourceFlags_PadDPad = 1 << 1,
- ImGuiNavDirSourceFlags_PadLStick = 1 << 2
-};
-
-enum ImGuiNavMoveFlags_
-{
- ImGuiNavMoveFlags_None = 0,
- ImGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side
- ImGuiNavMoveFlags_LoopY = 1 << 1,
- ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left)
- ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful for provided for completeness
- ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
- ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible.
- ImGuiNavMoveFlags_ScrollToEdge = 1 << 6
-};
-
-enum ImGuiNavForward
-{
- ImGuiNavForward_None,
- ImGuiNavForward_ForwardQueued,
- ImGuiNavForward_ForwardActive
-};
-
-enum ImGuiNavLayer
-{
- ImGuiNavLayer_Main = 0, // Main scrolling layer
- ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu)
- ImGuiNavLayer_COUNT
-};
-
enum ImGuiPopupPositionPolicy
{
ImGuiPopupPositionPolicy_Default,
@@ -1103,20 +1055,6 @@ struct ImGuiPopupData
ImGuiPopupData() { memset(this, 0, sizeof(*this)); OpenFrameCount = -1; }
};
-struct ImGuiNavItemData
-{
- ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window)
- ImGuiID ID; // Init,Move // Best candidate item ID
- ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
- ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space
- float DistBox; // Move // Best candidate box distance to current NavId
- float DistCenter; // Move // Best candidate center distance to current NavId
- float DistAxial; // Move // Best candidate axial distance to current NavId
-
- ImGuiNavItemData() { Clear(); }
- void Clear() { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; }
-};
-
enum ImGuiNextWindowDataFlags_
{
ImGuiNextWindowDataFlags_None = 0,
@@ -1178,17 +1116,36 @@ struct ImGuiLastItemData
ImGuiID ID;
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
- ImRect Rect;
- ImRect DisplayRect;
+ ImRect Rect; // Full rectangle
+ ImRect NavRect; // Navigation scoring rectangle (not displayed)
+ ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
};
+struct IMGUI_API ImGuiStackSizes
+{
+ short SizeOfIDStack;
+ short SizeOfColorStack;
+ short SizeOfStyleVarStack;
+ short SizeOfFontStack;
+ short SizeOfFocusScopeStack;
+ short SizeOfGroupStack;
+ short SizeOfItemFlagsStack;
+ short SizeOfBeginPopupStack;
+ short SizeOfDisabledStack;
+
+ ImGuiStackSizes() { memset(this, 0, sizeof(*this)); }
+ void SetToCurrentState();
+ void CompareWithCurrentState();
+};
+
// Data saved for each window pushed into the stack
struct ImGuiWindowStackData
{
ImGuiWindow* Window;
ImGuiLastItemData ParentLastItemDataBackup;
+ ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
};
struct ImGuiShrinkWidthItem
@@ -1207,6 +1164,70 @@ struct ImGuiPtrOrIndex
};
//-----------------------------------------------------------------------------
+// [SECTION] Navigation support
+//-----------------------------------------------------------------------------
+
+enum ImGuiActivateFlags_
+{
+ ImGuiActivateFlags_None = 0,
+ ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available.
+ ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available.
+ ImGuiActivateFlags_TryToPreserveState = 1 << 2 // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
+};
+
+enum ImGuiNavHighlightFlags_
+{
+ ImGuiNavHighlightFlags_None = 0,
+ ImGuiNavHighlightFlags_TypeDefault = 1 << 0,
+ ImGuiNavHighlightFlags_TypeThin = 1 << 1,
+ ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse.
+ ImGuiNavHighlightFlags_NoRounding = 1 << 3
+};
+
+enum ImGuiNavDirSourceFlags_
+{
+ ImGuiNavDirSourceFlags_None = 0,
+ ImGuiNavDirSourceFlags_Keyboard = 1 << 0,
+ ImGuiNavDirSourceFlags_PadDPad = 1 << 1,
+ ImGuiNavDirSourceFlags_PadLStick = 1 << 2
+};
+
+enum ImGuiNavMoveFlags_
+{
+ ImGuiNavMoveFlags_None = 0,
+ ImGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side
+ ImGuiNavMoveFlags_LoopY = 1 << 1,
+ ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left)
+ ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness
+ ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
+ ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
+ ImGuiNavMoveFlags_ScrollToEdge = 1 << 6,
+ ImGuiNavMoveFlags_Forwarded = 1 << 7,
+ ImGuiNavMoveFlags_DebugNoResult = 1 << 8
+};
+
+enum ImGuiNavLayer
+{
+ ImGuiNavLayer_Main = 0, // Main scrolling layer
+ ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu)
+ ImGuiNavLayer_COUNT
+};
+
+struct ImGuiNavItemData
+{
+ ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window)
+ ImGuiID ID; // Init,Move // Best candidate item ID
+ ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
+ ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space
+ float DistBox; // Move // Best candidate box distance to current NavId
+ float DistCenter; // Move // Best candidate center distance to current NavId
+ float DistAxial; // Move // Best candidate axial distance to current NavId
+
+ ImGuiNavItemData() { Clear(); }
+ void Clear() { Window = NULL; ID = FocusScopeId = 0; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; }
+};
+
+//-----------------------------------------------------------------------------
// [SECTION] Columns support
//-----------------------------------------------------------------------------
@@ -1370,21 +1391,6 @@ struct ImGuiMetricsConfig
}
};
-struct IMGUI_API ImGuiStackSizes
-{
- short SizeOfIDStack;
- short SizeOfColorStack;
- short SizeOfStyleVarStack;
- short SizeOfFontStack;
- short SizeOfFocusScopeStack;
- short SizeOfGroupStack;
- short SizeOfBeginPopupStack;
-
- ImGuiStackSizes() { memset(this, 0, sizeof(*this)); }
- void SetToCurrentState();
- void CompareWithCurrentState();
-};
-
//-----------------------------------------------------------------------------
// [SECTION] Generic context hooks
//-----------------------------------------------------------------------------
@@ -1504,37 +1510,41 @@ struct ImGuiContext
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem()
ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0
ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0
- ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0
+ ImGuiID NavActivateInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0.
+ ImGuiActivateFlags NavActivateFlags;
ImGuiID NavJustTabbedId; // Just tabbed to this id.
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
ImGuiKeyModFlags NavJustMovedToKeyMods;
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
+ ImGuiActivateFlags NavNextActivateFlags;
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
- ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
- int NavScoringCount; // Metrics for debugging
ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later.
int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid
bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover)
bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again.
- bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest
+
+ // Navigation: Init & Move Requests
+ bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd()
bool NavInitRequest; // Init request for appearing window to select first item
bool NavInitRequestFromMove;
ImGuiID NavInitResultId; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called)
ImRect NavInitResultRectRel; // Init request result rectangle (relative to parent window)
- bool NavMoveRequest; // Move request for this frame
- ImGuiNavMoveFlags NavMoveRequestFlags;
- ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu)
- ImGuiKeyModFlags NavMoveRequestKeyMods;
- ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request
+ bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame()
+ bool NavMoveScoringItems; // Move request submitted, still scoring incoming items
+ bool NavMoveForwardToNextFrame;
+ ImGuiNavMoveFlags NavMoveFlags;
+ ImGuiKeyModFlags NavMoveKeyMods;
+ ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down)
+ ImGuiDir NavMoveDirForDebug;
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
+ ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
+ int NavScoringDebugCount; // Metrics for debugging
ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow
- ImGuiNavItemData NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
+ ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag)
- ImGuiWindow* NavWrapRequestWindow; // Window which requested trying nav wrap-around.
- ImGuiNavMoveFlags NavWrapRequestFlags; // Wrap-around operation flags.
// Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
@@ -1591,14 +1601,14 @@ struct ImGuiContext
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
// Widget state
- ImVec2 LastValidMousePos;
+ ImVec2 MouseLastValidPos;
ImGuiInputTextState InputTextState;
ImFont InputTextPasswordFont;
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
- float ColorEditLastHue; // Backup of last Hue associated to LastColor[3], so we can restore Hue in lossy RGB<>HSV round trips
- float ColorEditLastSat; // Backup of last Saturation associated to LastColor[3], so we can restore Saturation in lossy RGB<>HSV round trips
- float ColorEditLastColor[3];
+ float ColorEditLastHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips
+ float ColorEditLastSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips
+ ImU32 ColorEditLastColor; // RGB value with alpha set to 0.
ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker.
ImGuiComboPreviewData ComboPreviewData;
float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
@@ -1607,7 +1617,9 @@ struct ImGuiContext
float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
- int TooltipOverrideCount;
+ float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
+ short DisabledStackSize;
+ short TooltipOverrideCount;
float TooltipSlowDelay; // Time before slow tooltips appears (FIXME: This is temporary until we merge in tooltip timer+priority work)
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
@@ -1711,12 +1723,11 @@ struct ImGuiContext
CurrentItemFlags = ImGuiItemFlags_None;
NavWindow = NULL;
- NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0;
+ NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0;
NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
+ NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
NavJustMovedToKeyMods = ImGuiKeyModFlags_None;
NavInputSource = ImGuiInputSource_None;
- NavScoringRect = ImRect();
- NavScoringCount = 0;
NavLayer = ImGuiNavLayer_Main;
NavIdTabCounter = INT_MAX;
NavIdIsAlive = false;
@@ -1727,13 +1738,13 @@ struct ImGuiContext
NavInitRequest = false;
NavInitRequestFromMove = false;
NavInitResultId = 0;
- NavMoveRequest = false;
- NavMoveRequestFlags = ImGuiNavMoveFlags_None;
- NavMoveRequestForward = ImGuiNavForward_None;
- NavMoveRequestKeyMods = ImGuiKeyModFlags_None;
- NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None;
- NavWrapRequestWindow = NULL;
- NavWrapRequestFlags = ImGuiNavMoveFlags_None;
+ NavMoveSubmitted = false;
+ NavMoveScoringItems = false;
+ NavMoveForwardToNextFrame = false;
+ NavMoveFlags = ImGuiNavMoveFlags_None;
+ NavMoveKeyMods = ImGuiKeyModFlags_None;
+ NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
+ NavScoringDebugCount = 0;
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
@@ -1763,16 +1774,17 @@ struct ImGuiContext
CurrentTableStackIdx = -1;
CurrentTabBar = NULL;
- LastValidMousePos = ImVec2(0.0f, 0.0f);
TempInputId = 0;
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
ColorEditLastHue = ColorEditLastSat = 0.0f;
- ColorEditLastColor[0] = ColorEditLastColor[1] = ColorEditLastColor[2] = FLT_MAX;
+ ColorEditLastColor = 0;
SliderCurrentAccum = 0.0f;
SliderCurrentAccumDirty = false;
DragCurrentAccumDirty = false;
DragCurrentAccum = 0.0f;
DragSpeedDefaultRatio = 1.0f / 100.0f;
+ DisabledAlphaBackup = 0.0f;
+ DisabledStackSize = 0;
ScrollbarClickDeltaToGrabCenter = 0.0f;
TooltipOverrideCount = 0;
TooltipSlowDelay = 0.50f;
@@ -1847,7 +1859,7 @@ struct IMGUI_API ImGuiWindowTempData
int CurrentTableIdx; // Current table index (into g.Tables)
ImGuiLayoutType LayoutType;
ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
- int FocusCounterRegular; // (Legacy Focus/Tabbing system) Sequential counter, start at -1 and increase as assigned via FocusableItemRegister() (FIXME-NAV: Needs redesign)
+ int FocusCounterRegular; // (Legacy Focus/Tabbing system) Sequential counter, start at -1 and increase when ImGuiItemFlags_Inputable (FIXME-NAV: Needs redesign)
int FocusCounterTabStop; // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through.
// Local parameters stacks
@@ -1856,7 +1868,6 @@ struct IMGUI_API ImGuiWindowTempData
float TextWrapPos; // Current text wrap pos.
ImVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
ImVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
- ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
};
// Storage for one window
@@ -1939,8 +1950,9 @@ struct IMGUI_API ImGuiWindow
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
ImDrawList DrawListInst;
- ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL.
- ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window == Top-level window.
+ ImGuiWindow* ParentWindow; // If we are a child _or_ popup _or_ docked window, this is pointing to our parent. Otherwise NULL.
+ ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes.
+ ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
@@ -2326,7 +2338,7 @@ namespace ImGui
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window);
IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
- IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
+ IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0);
@@ -2399,10 +2411,10 @@ namespace ImGui
// Basic Helpers for widget code
IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f);
IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f);
- IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemAddFlags flags = 0);
+ IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0);
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
- IMGUI_API void ItemFocusable(ImGuiWindow* window, ImGuiID id);
- IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged);
+ IMGUI_API void ItemInputable(ImGuiWindow* window, ImGuiID id);
+ IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
@@ -2413,15 +2425,15 @@ namespace ImGui
// Parameter stacks
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
- IMGUI_API void PushDisabled(bool disabled = true);
- IMGUI_API void PopDisabled();
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
+ // Currently refactoring focus/nav/tabbing system
// If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool focused = FocusableItemRegister(...)'
- // (New) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
+ // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
+ // (New) IMGUI_VERSION_NUM >= 18411: using 'ItemAdd(..., ImGuiItemAddFlags_Inputable)' and 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
// Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from regular widget to TempInputText()
- inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Focusable flag to ItemAdd()
+ inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd()
inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
#endif
@@ -2436,6 +2448,7 @@ namespace ImGui
IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
+ IMGUI_API void ClosePopupsExceptModals();
IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags);
@@ -2443,9 +2456,10 @@ namespace ImGui
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window);
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy);
- IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
// Menus
+ IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
+ IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true);
IMGUI_API bool MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true);
// Combos
@@ -2455,9 +2469,12 @@ namespace ImGui
// Gamepad/Keyboard Navigation
IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit);
+ IMGUI_API void NavInitRequestApplyResult();
IMGUI_API bool NavMoveRequestButNoResultYet();
+ IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags);
+ IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags);
IMGUI_API void NavMoveRequestCancel();
- IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags);
+ IMGUI_API void NavMoveRequestApplyResult();
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode);
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f);
@@ -2666,6 +2683,7 @@ namespace ImGui
// Debug Tools
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
+ IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
inline void DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); }
inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; }
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp
index c7223905e8c..945e739a700 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (tables and columns code)
/*
@@ -324,7 +324,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
const ImVec2 avail_size = GetContentRegionAvail();
ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
- if (use_child_window && IsClippedEx(outer_rect, 0, false))
+ if (use_child_window && IsClippedEx(outer_rect, 0))
{
ItemSize(outer_rect);
return false;
@@ -1170,7 +1170,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
KeepAliveID(column_id);
bool hovered = false, held = false;
- bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
+ bool pressed = ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_NoNavFocus);
if (pressed && IsMouseDoubleClicked(0))
{
TableSetColumnWidthAutoSingle(table, column_n);
@@ -1479,6 +1479,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
// Ensure frozen columns are ordered in their section. We still allow multiple frozen columns to be reordered.
+ // FIXME-TABLE: This work for preserving 2143 into 21|43. How about 4321 turning into 21|43? (preserve relative order in each section)
for (int column_n = 0; column_n < table->FreezeColumnsRequest; column_n++)
{
int order_n = table->DisplayOrderToIndex[column_n];
@@ -3987,7 +3988,7 @@ void ImGui::EndColumns()
const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH;
const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2));
KeepAliveID(column_id);
- if (IsClippedEx(column_hit_rect, column_id, false))
+ if (IsClippedEx(column_hit_rect, column_id)) // FIXME: Can be removed or replaced with a lower-level test
continue;
bool hovered = false, held = false;
diff --git a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp
index 55bc433f36c..2bb418c590c 100644
--- a/3rdparty/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp
+++ b/3rdparty/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.84 WIP
+// dear imgui, v1.85 WIP
// (widgets code)
/*
@@ -152,9 +152,13 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
-
ImGuiContext& g = *GImGui;
- IM_ASSERT(text != NULL);
+
+ // Accept null ranges
+ if (text == text_end)
+ text = text_end = "";
+
+ // Calculate length
const char* text_begin = text;
if (text_end == NULL)
text_end = text + strlen(text); // FIXME-OPT
@@ -201,7 +205,7 @@ void ImGui::TextEx(const char* text, const char* text_end, ImGuiTextFlags flags)
ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height));
while (line < text_end)
{
- if (IsClippedEx(line_rect, 0, false))
+ if (IsClippedEx(line_rect, 0))
break;
const char* line_end = (const char*)memchr(line, '\n', text_end - line);
@@ -269,6 +273,7 @@ void ImGui::TextV(const char* fmt, va_list args)
if (window->SkipItems)
return;
+ // FIXME-OPT: Handle the %s shortcut?
ImGuiContext& g = *GImGui;
const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args);
TextEx(g.TempBuffer, text_end, ImGuiTextFlags_NoWidthForLargeClippedText);
@@ -566,6 +571,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
ClearActiveID();
else
SetActiveID(id, window); // Hold on ID
+ if (!(flags & ImGuiButtonFlags_NoNavFocus))
+ SetFocusID(id, window);
g.ActiveIdMouseButton = mouse_button_clicked;
FocusWindow(window);
}
@@ -576,6 +583,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay;
if (!has_repeated_at_least_once)
pressed = true;
+ if (!(flags & ImGuiButtonFlags_NoNavFocus))
+ SetFocusID(id, window);
ClearActiveID();
}
@@ -600,13 +609,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
bool nav_activated_by_code = (g.NavActivateId == id);
bool nav_activated_by_inputs = IsNavInputTest(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed);
if (nav_activated_by_code || nav_activated_by_inputs)
- pressed = true;
- if (nav_activated_by_code || nav_activated_by_inputs || g.ActiveId == id)
{
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
- g.NavActivateId = id; // This is so SetActiveId assign a Nav source
+ pressed = true;
SetActiveID(id, window);
- if ((nav_activated_by_code || nav_activated_by_inputs) && !(flags & ImGuiButtonFlags_NoNavFocus))
+ g.ActiveIdSource = ImGuiInputSource_Nav;
+ if (!(flags & ImGuiButtonFlags_NoNavFocus))
SetFocusID(id, window);
}
}
@@ -1577,7 +1585,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
bool pressed = ButtonBehavior(bb, id, &hovered, &held);
const ImGuiID popup_id = ImHashStr("##ComboPopup", 0, id);
bool popup_open = IsPopupOpen(popup_id, ImGuiPopupFlags_None);
- if ((pressed || g.NavActivateId == id) && !popup_open)
+ if (pressed && !popup_open)
{
OpenPopupEx(popup_id, ImGuiPopupFlags_None);
popup_open = true;
@@ -2385,7 +2393,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
ItemSize(total_bb, style.FramePadding.y);
- if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemAddFlags_Focusable : 0))
+ if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
return false;
// Default format string when passing NULL
@@ -2402,21 +2410,23 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]);
const bool double_clicked = (hovered && g.IO.MouseDoubleClicked[0]);
- if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavInputId == id)
+ if (focus_requested || clicked || double_clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{
SetActiveID(id, window);
SetFocusID(id, window);
FocusWindow(window);
g.ActiveIdUsingNavDirMask = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
- if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavInputId == id))
- temp_input_is_active = true;
+ if (temp_input_allowed)
+ if (focus_requested || (clicked && g.IO.KeyCtrl) || double_clicked || g.NavActivateInputId == id)
+ temp_input_is_active = true;
}
+
// Experimental: simple click (without moving) turns Drag into an InputText
- // FIXME: Currently polling ImGuiConfigFlags_IsTouchScreen, may either poll an hypothetical ImGuiBackendFlags_HasKeyboard and/or an explicit drag settings.
if (g.IO.ConfigDragClickToInputText && temp_input_allowed && !temp_input_is_active)
if (g.ActiveId == id && hovered && g.IO.MouseReleased[0] && !IsMouseDragPastThreshold(0, g.IO.MouseDragThreshold * DRAG_MOUSE_THRESHOLD_FACTOR))
{
- g.NavInputId = id;
+ g.NavActivateId = g.NavActivateInputId = id;
+ g.NavActivateFlags = ImGuiActivateFlags_PreferInput;
temp_input_is_active = true;
}
}
@@ -3016,7 +3026,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
const bool temp_input_allowed = (flags & ImGuiSliderFlags_NoInput) == 0;
ItemSize(total_bb, style.FramePadding.y);
- if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemAddFlags_Focusable : 0))
+ if (!ItemAdd(total_bb, id, &frame_bb, temp_input_allowed ? ImGuiItemFlags_Inputable : 0))
return false;
// Default format string when passing NULL
@@ -3032,13 +3042,13 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
{
const bool focus_requested = temp_input_allowed && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0;
const bool clicked = (hovered && g.IO.MouseClicked[0]);
- if (focus_requested || clicked || g.NavActivateId == id || g.NavInputId == id)
+ if (focus_requested || clicked || g.NavActivateId == id || g.NavActivateInputId == id)
{
SetActiveID(id, window);
SetFocusID(id, window);
FocusWindow(window);
g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right);
- if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavInputId == id))
+ if (temp_input_allowed && (focus_requested || (clicked && g.IO.KeyCtrl) || g.NavActivateInputId == id))
temp_input_is_active = true;
}
}
@@ -3190,7 +3200,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
format = PatchFormatStringFloatToInt(format);
const bool hovered = ItemHoverable(frame_bb, id);
- if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id)
+ if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavActivateInputId == id)
{
SetActiveID(id, window);
SetFocusID(id, window);
@@ -3454,7 +3464,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
style.FramePadding.x = style.FramePadding.y;
ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups;
if (flags & ImGuiInputTextFlags_ReadOnly)
- PushDisabled(true);
+ BeginDisabled();
SameLine(0, style.ItemInnerSpacing.x);
if (ButtonEx("-", ImVec2(button_size, button_size), button_flags))
{
@@ -3468,7 +3478,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
value_changed = true;
}
if (flags & ImGuiInputTextFlags_ReadOnly)
- PopDisabled();
+ EndDisabled();
const char* label_end = FindRenderedTextEnd(label);
if (label != label_end)
@@ -3857,6 +3867,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
unsigned int c = *p_char;
// Filter non-printable (NB: isprint is unreliable! see #2467)
+ bool apply_named_filters = true;
if (c < 0x20)
{
bool pass = false;
@@ -3864,6 +3875,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput));
if (!pass)
return false;
+ apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted.
}
if (input_source != ImGuiInputSource_Clipboard)
@@ -3882,7 +3894,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f
return false;
// Generic named filters
- if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific))
+ if (apply_named_filters && (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank | ImGuiInputTextFlags_CharsScientific)))
{
// The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf.
// The standard mandate that programs starts in the "C" locale where the decimal point is '.'.
@@ -3979,16 +3991,21 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
ImGuiWindow* draw_window = window;
ImVec2 inner_size = frame_size;
+ ImGuiItemStatusFlags item_status_flags = 0;
if (is_multiline)
{
- if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemAddFlags_Focusable))
+ ImVec2 backup_pos = window->DC.CursorPos;
+ ItemSize(total_bb, style.FramePadding.y);
+ if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable))
{
- ItemSize(total_bb, style.FramePadding.y);
EndGroup();
return false;
}
+ item_status_flags = g.LastItemData.StatusFlags;
+ window->DC.CursorPos = backup_pos;
// We reproduce the contents of BeginChildFrame() in order to provide 'label' so our window internal data are easier to read/debug.
+ // FIXME-NAV: Pressing NavActivate will trigger general child activation right before triggering our own below. Harmless but bizarre.
PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]);
PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding);
PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize);
@@ -4011,8 +4028,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Support for internal ImGuiInputTextFlags_MergedItem flag, which could be redesigned as an ItemFlags if needed (with test performed in ItemAdd)
ItemSize(total_bb, style.FramePadding.y);
if (!(flags & ImGuiInputTextFlags_MergedItem))
- if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemAddFlags_Focusable))
+ if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable))
return false;
+ item_status_flags = g.LastItemData.StatusFlags;
}
const bool hovered = ItemHoverable(frame_bb, id);
if (hovered)
@@ -4021,11 +4039,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// We are only allowed to access the state if we are already the active widget.
ImGuiInputTextState* state = GetInputTextState(id);
- const bool focus_requested_by_code = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByCode) != 0;
- const bool focus_requested_by_tabbing = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
+ const bool focus_requested_by_code = (item_status_flags & ImGuiItemStatusFlags_FocusedByCode) != 0;
+ const bool focus_requested_by_tabbing = (item_status_flags & ImGuiItemStatusFlags_FocusedByTabbing) != 0;
const bool user_clicked = hovered && io.MouseClicked[0];
- const bool user_nav_input_start = (g.ActiveId != id) && ((g.NavInputId == id) || (g.NavActivateId == id && g.NavInputSource == ImGuiInputSource_Keyboard));
+ const bool user_nav_input_start = (g.ActiveId != id) && (g.NavActivateInputId == id || g.NavActivateId == id);
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
@@ -4252,6 +4270,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) && !is_readonly && is_undoable);
const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && !is_readonly && is_undoable;
+ // We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
+ const bool is_validate_enter = IsKeyPressedMap(ImGuiKey_Enter) || IsKeyPressedMap(ImGuiKey_KeyPadEnter);
+ const bool is_validate_nav = (IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed) && !IsKeyPressedMap(ImGuiKey_Space)) || IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed);
+ const bool is_cancel = IsKeyPressedMap(ImGuiKey_Escape) || IsNavInputTest(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed);
+
if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); }
else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); }
@@ -4272,7 +4295,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
}
- else if (IsKeyPressedMap(ImGuiKey_Enter) || IsKeyPressedMap(ImGuiKey_KeyPadEnter))
+ else if (is_validate_enter)
{
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl))
@@ -4286,7 +4309,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->OnKeyPressed((int)c);
}
}
- else if (IsKeyPressedMap(ImGuiKey_Escape))
+ else if (is_validate_nav)
+ {
+ IM_ASSERT(!is_validate_enter);
+ enter_pressed = clear_active_id = true;
+ }
+ else if (is_cancel)
{
clear_active_id = cancel_edit = true;
}
@@ -4768,6 +4796,30 @@ bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flag
return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha);
}
+// ColorEdit supports RGB and HSV inputs. In case of RGB input resulting color may have undefined hue and/or saturation.
+// Since widget displays both RGB and HSV values we must preserve hue and saturation to prevent these values resetting.
+static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V)
+{
+ // This check is optional. Suppose we have two color widgets side by side, both widgets display different colors, but both colors have hue and/or saturation undefined.
+ // With color check: hue/saturation is preserved in one widget. Editing color in one widget would reset hue/saturation in another one.
+ // Without color check: common hue/saturation would be displayed in all widgets that have hue/saturation undefined.
+ // g.ColorEditLastColor is stored as ImU32 RGB value: this essentially gives us color equality check with reduced precision.
+ // Tiny external color changes would not be detected and this check would still pass. This is OK, since we only restore hue/saturation _only_ if they are undefined,
+ // therefore this change flipping hue/saturation from undefined to a very tiny value would still be represented in color picker.
+ ImGuiContext& g = *GImGui;
+ if (g.ColorEditLastColor != ImGui::ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)))
+ return;
+
+ // When S == 0, H is undefined.
+ // When H == 1 it wraps around to 0.
+ if (*S == 0.0f || (*H == 0.0f && g.ColorEditLastHue == 1))
+ *H = g.ColorEditLastHue;
+
+ // When V == 0, S is undefined.
+ if (*V == 0.0f)
+ *S = g.ColorEditLastSat;
+}
+
// Edit colors components (each component in 0.0f..1.0f range).
// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item.
@@ -4823,13 +4875,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
{
// Hue is lost when converting from greyscale rgb (saturation=0). Restore it.
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
- if (memcmp(g.ColorEditLastColor, col, sizeof(float) * 3) == 0)
- {
- if (f[1] == 0)
- f[0] = g.ColorEditLastHue;
- if (f[2] == 0)
- f[1] = g.ColorEditLastSat;
- }
+ ColorEditRestoreHS(col, &f[0], &f[1], &f[2]);
}
int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) };
@@ -4964,7 +5010,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
g.ColorEditLastHue = f[0];
g.ColorEditLastSat = f[1];
ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]);
- memcpy(g.ColorEditLastColor, f, sizeof(float) * 3);
+ g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(f[0], f[1], f[2], 0));
}
if ((flags & ImGuiColorEditFlags_DisplayRGB) && (flags & ImGuiColorEditFlags_InputHSV))
ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]);
@@ -5099,13 +5145,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
{
// Hue is lost when converting from greyscale rgb (saturation=0). Restore it.
ColorConvertRGBtoHSV(R, G, B, H, S, V);
- if (memcmp(g.ColorEditLastColor, col, sizeof(float) * 3) == 0)
- {
- if (S == 0)
- H = g.ColorEditLastHue;
- if (V == 0)
- S = g.ColorEditLastSat;
- }
+ ColorEditRestoreHS(col, &H, &S, &V);
}
else if (flags & ImGuiColorEditFlags_InputHSV)
{
@@ -5158,6 +5198,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
{
S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1));
V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1));
+
+ // Greatly reduces hue jitter and reset to 0 when hue == 255 and color is rapidly modified using SV square.
+ if (g.ColorEditLastColor == ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0)))
+ H = g.ColorEditLastHue;
value_changed = value_changed_sv = true;
}
if (!(flags & ImGuiColorEditFlags_NoOptions))
@@ -5231,10 +5275,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
{
if (flags & ImGuiColorEditFlags_InputRGB)
{
- ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10 * 1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]);
+ ColorConvertHSVtoRGB(H, S, V, col[0], col[1], col[2]);
g.ColorEditLastHue = H;
g.ColorEditLastSat = S;
- memcpy(g.ColorEditLastColor, col, sizeof(float) * 3);
+ g.ColorEditLastColor = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 0));
}
else if (flags & ImGuiColorEditFlags_InputHSV)
{
@@ -5288,13 +5332,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
G = col[1];
B = col[2];
ColorConvertRGBtoHSV(R, G, B, H, S, V);
- if (memcmp(g.ColorEditLastColor, col, sizeof(float) * 3) == 0) // Fix local Hue as display below will use it immediately.
- {
- if (S == 0)
- H = g.ColorEditLastHue;
- if (V == 0)
- S = g.ColorEditLastSat;
- }
+ ColorEditRestoreHS(col, &H, &S, &V); // Fix local Hue as display below will use it immediately.
}
else if (flags & ImGuiColorEditFlags_InputHSV)
{
@@ -5901,12 +5939,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
toggled = true;
}
- if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open)
+ if (g.NavId == id && g.NavMoveDir == ImGuiDir_Left && is_open)
{
toggled = true;
NavMoveRequestCancel();
}
- if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority?
+ if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority?
{
toggled = true;
NavMoveRequestCancel();
@@ -5977,7 +6015,7 @@ void ImGui::TreePush(const char* str_id)
ImGuiWindow* window = GetCurrentWindow();
Indent();
window->DC.TreeDepth++;
- PushID(str_id ? str_id : "#TreePush");
+ PushID(str_id);
}
void ImGui::TreePush(const void* ptr_id)
@@ -5985,7 +6023,7 @@ void ImGui::TreePush(const void* ptr_id)
ImGuiWindow* window = GetCurrentWindow();
Indent();
window->DC.TreeDepth++;
- PushID(ptr_id ? ptr_id : (const void*)"#TreePush");
+ PushID(ptr_id);
}
void ImGui::TreePushOverrideID(ImGuiID id)
@@ -6148,20 +6186,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
window->ClipRect.Max.x = window->ParentWorkRect.Max.x;
}
- bool item_add;
const bool disabled_item = (flags & ImGuiSelectableFlags_Disabled) != 0;
- if (disabled_item)
- {
- ImGuiItemFlags backup_item_flags = g.CurrentItemFlags;
- g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
- item_add = ItemAdd(bb, id);
- g.CurrentItemFlags = backup_item_flags;
- }
- else
- {
- item_add = ItemAdd(bb, id);
- }
-
+ const bool item_add = ItemAdd(bb, id, NULL, disabled_item ? ImGuiItemFlags_Disabled : ImGuiItemFlags_None);
if (span_all_columns)
{
window->ClipRect.Min.x = backup_clip_rect_min_x;
@@ -6173,7 +6199,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
const bool disabled_global = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0;
if (disabled_item && !disabled_global) // Only testing this as an optimization
- PushDisabled(true);
+ BeginDisabled();
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
// which would be advantageous since most selectable are not selected.
@@ -6210,7 +6236,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
{
if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent)
{
- SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos));
+ SetNavID(id, window->DC.NavLayerCurrent, window->DC.NavFocusScopeIdCurrent, ImRect(bb.Min - window->Pos, bb.Max - window->Pos)); // (bb == NavRect)
g.NavDisableHighlight = true;
}
}
@@ -6246,10 +6272,10 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
CloseCurrentPopup();
if (disabled_item && !disabled_global)
- PopDisabled();
+ EndDisabled();
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, g.LastItemData.StatusFlags);
- return pressed;
+ return pressed; //-V1020
}
bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg)
@@ -6475,7 +6501,7 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
float v0 = values_getter(data, (0 + values_offset) % values_count);
float t0 = 0.0f;
ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) ); // Point in the normalized space of our target rectangle
- float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands
+ float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (1 + scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands
const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram);
const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered);
@@ -6691,21 +6717,21 @@ void ImGui::EndMenuBar()
// Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings.
if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
{
+ // Try to find out if the request is for one of our child menu
ImGuiWindow* nav_earliest_child = g.NavWindow;
while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu))
nav_earliest_child = nav_earliest_child->ParentWindow;
- if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && g.NavMoveRequestForward == ImGuiNavForward_None)
+ if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
{
// To do so we claim focus back, restore NavId and then process the movement request for yet another frame.
- // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth the hassle/cost)
+ // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth bothering)
const ImGuiNavLayer layer = ImGuiNavLayer_Menu;
IM_ASSERT(window->DC.NavLayersActiveMaskNext & (1 << layer)); // Sanity check
FocusWindow(window);
SetNavID(window->NavLastIds[layer], layer, 0, window->NavRectRel[layer]);
g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection.
g.NavDisableMouseHover = g.NavMousePosDirty = true;
- g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
- NavMoveRequestCancel();
+ NavMoveRequestForward(g.NavMoveDir, g.NavMoveClipDir, g.NavMoveFlags); // Repeat
}
}
@@ -6794,7 +6820,7 @@ void ImGui::EndMainMenuBar()
End();
}
-bool ImGui::BeginMenu(const char* label, bool enabled)
+bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
@@ -6838,7 +6864,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
ImVec2 popup_pos, pos = window->DC.CursorPos;
PushID(label);
if (!enabled)
- PushDisabled();
+ BeginDisabled();
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
{
@@ -6857,21 +6883,23 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
}
else
{
- // Menu inside a menu
+ // Menu inside a regular/vertical menu
// (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f.
// Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system.
popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y);
- float icon_w = 0.0f; // FIXME: This not currently exposed for BeginMenu() however you can call window->DC.MenuColumns.DeclColumns(w, 0, 0, 0) yourself
+ float icon_w = (icon && icon[0]) ? CalcTextSize(icon, NULL).x : 0.0f;
float checkmark_w = IM_FLOOR(g.FontSize * 1.20f);
float min_w = window->DC.MenuColumns.DeclColumns(icon_w, label_size.x, 0.0f, checkmark_w); // Feedback to next frame
float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w);
ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
pressed = Selectable("", menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f));
RenderText(text_pos, label);
+ if (icon_w > 0.0f)
+ RenderText(pos + ImVec2(offsets->OffsetIcon, 0.0f), icon);
RenderArrow(window->DrawList, pos + ImVec2(offsets->OffsetMark + extra_w + g.FontSize * 0.30f, 0.0f), GetColorU32(ImGuiCol_Text), ImGuiDir_Right);
}
if (!enabled)
- PopDisabled();
+ EndDisabled();
const bool hovered = (g.HoveredId == id) && enabled;
if (menuset_is_open)
@@ -6884,38 +6912,30 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
// Close menu when not hovering it anymore unless we are moving roughly in the direction of the menu
// Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_toward_other_child_menu = false;
-
ImGuiWindow* child_menu_window = (g.BeginPopupStack.Size < g.OpenPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].SourceWindow == window) ? g.OpenPopupStack[g.BeginPopupStack.Size].Window : NULL;
if (g.HoveredWindow == window && child_menu_window != NULL && !(window->Flags & ImGuiWindowFlags_MenuBar))
{
- // FIXME-DPI: Values should be derived from a master "scale" factor.
+ float ref_unit = g.FontSize; // FIXME-DPI
ImRect next_window_rect = child_menu_window->Rect();
- ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta;
+ ImVec2 ta = (g.IO.MousePos - g.IO.MouseDelta);
ImVec2 tb = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR();
ImVec2 tc = (window->Pos.x < child_menu_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR();
- float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack.
- ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues
- tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
- tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f);
+ float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, ref_unit * 0.5f, ref_unit * 2.5f); // add a bit of extra slack.
+ ta.x += (window->Pos.x < child_menu_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues (FIXME: ??)
+ tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -ref_unit * 8.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale?
+ tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +ref_unit * 8.0f);
moving_toward_other_child_menu = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos);
- //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
+ //GetForegroundDrawList()->AddTriangleFilled(ta, tb, tc, moving_toward_other_child_menu ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); // [DEBUG]
}
-
- // FIXME: Hovering a disabled BeginMenu or MenuItem won't close us
if (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_toward_other_child_menu)
want_close = true;
- if (!menu_is_open && hovered && pressed) // Click to open
+ // Open
+ if (!menu_is_open && pressed) // Click/activate to open
want_open = true;
else if (!menu_is_open && hovered && !moving_toward_other_child_menu) // Hover to open
want_open = true;
-
- if (g.NavActivateId == id)
- {
- want_close = menu_is_open;
- want_open = !menu_is_open;
- }
- if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
+ if (g.NavId == id && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open
{
want_open = true;
NavMoveRequestCancel();
@@ -6933,7 +6953,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
{
want_open = true;
}
- else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open
+ else if (g.NavId == id && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open
{
want_open = true;
NavMoveRequestCancel();
@@ -6972,6 +6992,11 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
return menu_is_open;
}
+bool ImGui::BeginMenu(const char* label, bool enabled)
+{
+ return BeginMenuEx(label, NULL, enabled);
+}
+
void ImGui::EndMenu()
{
// Nav: When a left move request _within our child menu_ failed, close ourselves (the _parent_ menu).
@@ -6979,11 +7004,12 @@ void ImGui::EndMenu()
// However, it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction.
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
- if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical)
- {
- ClosePopupToLevel(g.BeginPopupStack.Size, true);
- NavMoveRequestCancel();
- }
+ if (g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical)
+ if (g.NavWindow && (g.NavWindow->RootWindowForNav->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->RootWindowForNav->ParentWindow == window)
+ {
+ ClosePopupToLevel(g.BeginPopupStack.Size, true);
+ NavMoveRequestCancel();
+ }
EndPopup();
}
@@ -7004,7 +7030,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
bool pressed;
PushID(label);
if (!enabled)
- PushDisabled(true);
+ BeginDisabled();
const ImGuiSelectableFlags flags = ImGuiSelectableFlags_SelectOnRelease | ImGuiSelectableFlags_SetNavIdOnHover;
const ImGuiMenuColumns* offsets = &window->DC.MenuColumns;
if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
@@ -7013,10 +7039,11 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
// Note that in this situation: we don't render the shortcut, we render a highlight instead of the selected tick mark.
float w = label_size.x;
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f);
+ ImVec2 text_pos(window->DC.CursorPos.x + offsets->OffsetLabel, window->DC.CursorPos.y + window->DC.CurrLineTextBaseOffset);
PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y));
pressed = Selectable("", selected, flags, ImVec2(w, 0.0f));
PopStyleVar();
- RenderText(pos + ImVec2(offsets->OffsetLabel, 0.0f), label);
+ RenderText(text_pos, label);
window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
}
else
@@ -7044,7 +7071,7 @@ bool ImGui::MenuItemEx(const char* label, const char* icon, const char* shortcut
}
IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Checkable | (selected ? ImGuiItemStatusFlags_Checked : 0));
if (!enabled)
- PopDisabled();
+ EndDisabled();
PopID();
return pressed;
diff --git a/3rdparty/bgfx/3rdparty/glslang/CHANGES.md b/3rdparty/bgfx/3rdparty/glslang/CHANGES.md
index 27b002e8427..ad4fa400856 100644
--- a/3rdparty/bgfx/3rdparty/glslang/CHANGES.md
+++ b/3rdparty/bgfx/3rdparty/glslang/CHANGES.md
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).
+## 11.6.0 2021-08-25
+
+### Other changes
+* Atomic memory function only for shader storage block member or shared variable
+* Add support for gl_MaxVaryingVectors for ogl
+* Fix loading bool arrays from interface blocks
+* Generate separate stores for partially swizzled memory stores
+* Allow layout(std430) uniform with GL_EXT_scalar_block_layout
+* Support for pragma STDGL invariant(all)
+* Support for GL_NV_ray_tracing_motion_blur
+
## 11.5.0 2021-06-23
### Other changes
diff --git a/3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h b/3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h
index 50146da1043..93c98bf6269 100644
--- a/3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h
+++ b/3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h
@@ -69,6 +69,9 @@ const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
//SPV_NV_raytracing
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
+//SPV_NV_ray_tracing_motion_blur
+const char* const E_SPV_NV_ray_tracing_motion_blur = "SPV_NV_ray_tracing_motion_blur";
+
//SPV_NV_shading_rate
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
diff --git a/3rdparty/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp b/3rdparty/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp
index c8a73a6b285..63932c2b1ad 100644
--- a/3rdparty/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp
@@ -1033,6 +1033,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
return spv::BuiltInIncomingRayFlagsKHR;
case glslang::EbvGeometryIndex:
return spv::BuiltInRayGeometryIndexKHR;
+ case glslang::EbvCurrentRayTimeNV:
+ builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+ builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+ return spv::BuiltInCurrentRayTimeNV;
// barycentrics
case glslang::EbvBaryCoordNV:
@@ -3018,6 +3022,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpIgnoreIntersectionNV:
case glslang::EOpTerminateRayNV:
case glslang::EOpTraceNV:
+ case glslang::EOpTraceRayMotionNV:
case glslang::EOpTraceKHR:
case glslang::EOpExecuteCallableNV:
case glslang::EOpExecuteCallableKHR:
@@ -3317,9 +3322,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst();
operands.push_back(builder.makeIntConstant(cond ? 1 : 0));
} else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) ||
+ (arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) ||
(arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) {
- const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : 1;
- const int set = glslangOp == glslang::EOpTraceKHR ? 0 : 1;
+ const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1);
+ const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0;
+
const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst();
auto itNode = locationToSymbol[set].find(location);
visitSymbol(itNode->second);
@@ -3377,7 +3384,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
const auto& spirvInst = node->getSpirvInstruction();
if (spirvInst.set == "") {
std::vector<spv::IdImmediate> idImmOps;
- for (int i = 0; i < glslangOperands.size(); ++i) {
+ for (unsigned int i = 0; i < glslangOperands.size(); ++i) {
if (glslangOperands[i]->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Translate the constant to a literal value
std::vector<unsigned> literals;
@@ -3933,12 +3940,14 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler)
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
return builder.makeFloatType(16);
- case glslang::EbtInt64: return builder.makeIntType(64);
+ case glslang::EbtInt64:
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
- builder.addCapability(spv::CapabilityFloat16ImageAMD);
- case glslang::EbtUint64: return builder.makeUintType(64);
+ builder.addCapability(spv::CapabilityInt64ImageEXT);
+ return builder.makeIntType(64);
+ case glslang::EbtUint64:
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
- builder.addCapability(spv::CapabilityFloat16ImageAMD);
+ builder.addCapability(spv::CapabilityInt64ImageEXT);
+ return builder.makeUintType(64);
#endif
default:
assert(0);
@@ -7499,6 +7508,8 @@ spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op
break;
case glslang::EOpReadFirstInvocation:
opCode = spv::OpSubgroupFirstInvocationKHR;
+ if (builder.isVectorType(typeId))
+ return CreateInvocationsVectorOperation(opCode, groupOperation, typeId, operands);
break;
case glslang::EOpBallot:
{
@@ -7623,7 +7634,7 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
op == spv::OpGroupFMax || op == spv::OpGroupUMax || op == spv::OpGroupSMax ||
op == spv::OpGroupFAdd || op == spv::OpGroupIAdd || op == spv::OpGroupBroadcast ||
- op == spv::OpSubgroupReadInvocationKHR ||
+ op == spv::OpSubgroupReadInvocationKHR || op == spv::OpSubgroupFirstInvocationKHR ||
op == spv::OpGroupFMinNonUniformAMD || op == spv::OpGroupUMinNonUniformAMD ||
op == spv::OpGroupSMinNonUniformAMD ||
op == spv::OpGroupFMaxNonUniformAMD || op == spv::OpGroupUMaxNonUniformAMD ||
@@ -7652,6 +7663,8 @@ spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv
spvGroupOperands.push_back(scalar);
spv::IdImmediate operand = { true, operands[1] };
spvGroupOperands.push_back(operand);
+ } else if (op == spv::OpSubgroupFirstInvocationKHR) {
+ spvGroupOperands.push_back(scalar);
} else if (op == spv::OpGroupBroadcast) {
spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
spvGroupOperands.push_back(scope);
@@ -8322,6 +8335,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
case glslang::EOpTraceNV:
builder.createNoResultOp(spv::OpTraceNV, operands);
return 0;
+ case glslang::EOpTraceRayMotionNV:
+ builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
+ builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
+ builder.createNoResultOp(spv::OpTraceRayMotionNV, operands);
+ return 0;
case glslang::EOpTraceKHR:
builder.createNoResultOp(spv::OpTraceRayKHR, operands);
return 0;
diff --git a/3rdparty/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp b/3rdparty/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp
index 6751dec215e..e83306ebcbf 100644
--- a/3rdparty/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp
@@ -2812,6 +2812,7 @@ void Builder::accessChainStore(Id rvalue, Decoration nonUniform, spv::MemoryAcce
accessChain.component == NoResult) {
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle[i]));
+ accessChain.instr = NoResult;
Id base = collapseAccessChain();
addDecoration(base, nonUniform);
diff --git a/3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp b/3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp
index 31b20a1f24a..dbdf7077a60 100644
--- a/3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp
@@ -426,6 +426,7 @@ const char* BuiltInString(int builtIn)
case BuiltInSMCountNV: return "SMCountNV";
case BuiltInWarpIDNV: return "WarpIDNV";
case BuiltInSMIDNV: return "SMIDNV";
+ case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV";
default: return "Bad";
}
@@ -916,6 +917,7 @@ const char* CapabilityString(int info)
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV";
case CapabilityRayTracingNV: return "RayTracingNV";
+ case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV";
case CapabilityRayTracingKHR: return "RayTracingKHR";
case CapabilityRayQueryKHR: return "RayQueryKHR";
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
@@ -1382,6 +1384,7 @@ const char* OpcodeString(int op)
case OpTerminateRayNV: return "OpTerminateRayNV";
case OpTerminateRayKHR: return "OpTerminateRayKHR";
case OpTraceNV: return "OpTraceNV";
+ case OpTraceRayMotionNV: return "OpTraceRayMotionNV";
case OpTraceRayKHR: return "OpTraceRayKHR";
case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR";
case OpExecuteCallableNV: return "OpExecuteCallableNV";
@@ -2812,6 +2815,20 @@ void Parameterize()
InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'");
InstructionDesc[OpTraceNV].setResultAndType(false, false);
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'");
+ InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'");
+ InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false);
+
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'");
InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'");
diff --git a/3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp b/3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp
index 317db81f17a..e0fe24980d3 100644
--- a/3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp
+++ b/3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp
@@ -652,6 +652,7 @@ enum BuiltIn {
BuiltInHitTNV = 5332,
BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
+ BuiltInCurrentRayTimeNV = 5334,
BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352,
@@ -988,6 +989,7 @@ enum Capability {
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilityRayTracingNV = 5340,
+ CapabilityRayTracingMotionBlurNV = 5341,
CapabilityVulkanMemoryModel = 5345,
CapabilityVulkanMemoryModelKHR = 5345,
CapabilityVulkanMemoryModelDeviceScope = 5346,
@@ -1503,6 +1505,8 @@ enum Op {
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
@@ -2090,6 +2094,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case OpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
diff --git a/3rdparty/bgfx/3rdparty/glslang/build_info.h b/3rdparty/bgfx/3rdparty/glslang/build_info.h
index 1206701d954..661c4a3c1c4 100644
--- a/3rdparty/bgfx/3rdparty/glslang/build_info.h
+++ b/3rdparty/bgfx/3rdparty/glslang/build_info.h
@@ -35,7 +35,7 @@
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 11
-#define GLSLANG_VERSION_MINOR 5
+#define GLSLANG_VERSION_MINOR 6
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp
index 02aac3c69e9..39b3ecac9fb 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp
@@ -4017,12 +4017,12 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
- if (argBias != nullptr)
- txsample->getSequence().push_back(argBias);
-
if (argOffset != nullptr)
txsample->getSequence().push_back(argOffset);
+ if (argBias != nullptr)
+ txsample->getSequence().push_back(argBias);
+
node = convertReturn(txsample, sampler);
break;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseables.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseables.cpp
index 4673b460119..15918dc3769 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseables.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseables.cpp
@@ -665,8 +665,8 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
{ "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS, true },
{ "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS, true },
- { "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS, true },
- { "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS, true },
+ { "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,F", EShLangPS, true },
+ { "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,F,I", EShLangPS, true },
// TODO: FXC accepts int/uint samplers here. unclear what that means.
{ "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS, true },
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h
index 1d9da12d6fd..c8203c22329 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h
@@ -270,6 +270,7 @@ enum TBuiltInVariable {
EbvWorldToObject,
EbvWorldToObject3x4,
EbvIncomingRayFlags,
+ EbvCurrentRayTimeNV,
// barycentrics
EbvBaryCoordNV,
EbvBaryCoordNoPerspNV,
@@ -475,6 +476,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
case EbvObjectToWorld: return "ObjectToWorldNV";
case EbvWorldToObject: return "WorldToObjectNV";
+ case EbvCurrentRayTimeNV: return "CurrentRayTimeNV";
case EbvBaryCoordNV: return "BaryCoordNV";
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Common.h b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Common.h
index 048887f4680..a6d37c71528 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Common.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Common.h
@@ -62,7 +62,7 @@ std::string to_string(const T& val) {
}
#endif
-#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || defined MINGW_HAS_SECURE_API
+#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API
#include <basetsd.h>
#ifndef snprintf
#define snprintf sprintf_s
@@ -214,7 +214,7 @@ template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
//
// Create a TString object from an integer.
//
-#if defined _MSC_VER || defined MINGW_HAS_SECURE_API
+#if defined _MSC_VER || MINGW_HAS_SECURE_API
inline const TString String(const int i, const int base = 10)
{
char text[16]; // 32 bit ints are at most 10 digits in base 10
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Types.h b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Types.h
index a6bf191d75f..f4f3f341d14 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Types.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/Types.h
@@ -741,6 +741,16 @@ public:
}
}
+ bool isUniform() const
+ {
+ switch (storage) {
+ case EvqUniform:
+ return true;
+ default:
+ return false;
+ }
+ }
+
bool isIo() const
{
switch (storage) {
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/intermediate.h b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/intermediate.h
index 172c09cf351..595bd623dbf 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/Include/intermediate.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/Include/intermediate.h
@@ -926,6 +926,7 @@ enum TOperator {
EOpMul32x16,
EOpTraceNV,
+ EOpTraceRayMotionNV,
EOpTraceKHR,
EOpReportIntersection,
EOpIgnoreIntersectionNV,
@@ -1642,6 +1643,7 @@ public:
~TIntermAggregate() { delete pragmaTable; }
virtual TIntermAggregate* getAsAggregate() { return this; }
virtual const TIntermAggregate* getAsAggregate() const { return this; }
+ virtual void updatePrecision();
virtual void setOperator(TOperator o) { op = o; }
virtual TIntermSequence& getSequence() { return sequence; }
virtual const TIntermSequence& getSequence() const { return sequence; }
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp
index 4629cc2da50..7f5d4c4f245 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Constant.cpp
@@ -531,7 +531,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
// Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
- unionArray[i].getIConst() == 0x80000000
+ static_cast<unsigned int>(unionArray[i].getIConst()) == 0x80000000
? -0x7FFFFFFF - 1
: -unionArray[i].getIConst());
break;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
index a79925d3e55..ee4e2cab56e 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp
@@ -1864,6 +1864,22 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
+ if (profile != EEsProfile && version == 450) {
+ commonBuiltins.append(
+ "uint atomicCounterAddARB(atomic_uint, uint);"
+ "uint atomicCounterSubtractARB(atomic_uint, uint);"
+ "uint atomicCounterMinARB(atomic_uint, uint);"
+ "uint atomicCounterMaxARB(atomic_uint, uint);"
+ "uint atomicCounterAndARB(atomic_uint, uint);"
+ "uint atomicCounterOrARB(atomic_uint, uint);"
+ "uint atomicCounterXorARB(atomic_uint, uint);"
+ "uint atomicCounterExchangeARB(atomic_uint, uint);"
+ "uint atomicCounterCompSwapARB(atomic_uint, uint, uint);"
+
+ "\n");
+ }
+
+
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append(
"uint atomicCounterAdd(atomic_uint, uint);"
@@ -4661,7 +4677,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
}
- // Builtins for GL_NV_ray_tracing/GL_EXT_ray_tracing/GL_EXT_ray_query
+ // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query
if (profile != EEsProfile && version >= 460) {
commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);"
"void rayQueryTerminateEXT(rayQueryEXT);"
@@ -4690,6 +4706,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
stageBuiltins[EShLangRayGen].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+ "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
@@ -4704,12 +4721,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"\n");
stageBuiltins[EShLangClosestHit].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+ "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
"\n");
stageBuiltins[EShLangMiss].append(
"void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
+ "void traceRayMotionNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);"
"void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);"
"void executeCallableNV(uint, int);"
"void executeCallableEXT(uint, int);"
@@ -5918,6 +5937,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
+ "in float gl_CurrentRayTimeNV;"
"\n";
const char *hitDecls =
"in uvec3 gl_LaunchIDNV;"
@@ -5953,6 +5973,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in mat3x4 gl_WorldToObject3x4EXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
+ "in float gl_CurrentRayTimeNV;"
"\n";
const char *missDecls =
"in uvec3 gl_LaunchIDNV;"
@@ -5971,6 +5992,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"in float gl_RayTmaxEXT;"
"in uint gl_IncomingRayFlagsNV;"
"in uint gl_IncomingRayFlagsEXT;"
+ "in float gl_CurrentRayTimeNV;"
"\n";
const char *callableDecls =
@@ -7679,6 +7701,11 @@ static void BuiltInVariable(const char* name, TBuiltInVariable builtIn, TSymbolT
symQualifier.builtIn = builtIn;
}
+static void RetargetVariable(const char* from, const char* to, TSymbolTable& symbolTable)
+{
+ symbolTable.retargetSymbol(from, to);
+}
+
//
// For built-in variables inside a named block.
// SpecialQualifier() won't ever go inside a block; their member's qualifier come
@@ -7746,8 +7773,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) {
// treat these built-ins as aliases of VertexIndex and InstanceIndex
- BuiltInVariable("gl_VertexID", EbvVertexIndex, symbolTable);
- BuiltInVariable("gl_InstanceID", EbvInstanceIndex, symbolTable);
+ RetargetVariable("gl_InstanceID", "gl_InstanceIndex", symbolTable);
+ RetargetVariable("gl_VertexID", "gl_VertexIndex", symbolTable);
}
if (profile != EEsProfile) {
@@ -8261,6 +8288,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("atomicCounter" , 1, &E_GL_ARB_shader_atomic_counters);
}
+ // E_GL_ARB_shader_atomic_counter_ops
+ if (profile != EEsProfile && version == 450) {
+ symbolTable.setFunctionExtensions("atomicCounterAddARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterSubtractARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterMinARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterMaxARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterAndARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterOrARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterXorARB" , 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterExchangeARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+ symbolTable.setFunctionExtensions("atomicCounterCompSwapARB", 1, &E_GL_ARB_shader_atomic_counter_ops);
+ }
+
// E_GL_ARB_derivative_control
if (profile != EEsProfile && version < 450) {
symbolTable.setFunctionExtensions("dFdxFine", 1, &E_GL_ARB_derivative_control);
@@ -8789,11 +8829,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setVariableExtensions("gl_WorldToObject3x4EXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
+ symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
symbolTable.setFunctionExtensions("traceNV", 1, &E_GL_NV_ray_tracing);
+ symbolTable.setFunctionExtensions("traceRayMotionNV", 1, &E_GL_NV_ray_tracing_motion_blur);
symbolTable.setFunctionExtensions("traceRayEXT", 1, &E_GL_EXT_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionNV", 1, &E_GL_NV_ray_tracing);
symbolTable.setFunctionExtensions("reportIntersectionEXT", 1, &E_GL_EXT_ray_tracing);
@@ -8837,6 +8879,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_IncomingRayFlagsNV", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable);
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
+ BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable);
// GL_ARB_shader_ballot
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
@@ -9261,6 +9304,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("clockRealtimeEXT", EOpReadClockDeviceKHR);
symbolTable.relateToOperator("clockRealtime2x32EXT", EOpReadClockDeviceKHR);
+ if (profile != EEsProfile && version == 450) {
+ symbolTable.relateToOperator("atomicCounterAddARB", EOpAtomicCounterAdd);
+ symbolTable.relateToOperator("atomicCounterSubtractARB", EOpAtomicCounterSubtract);
+ symbolTable.relateToOperator("atomicCounterMinARB", EOpAtomicCounterMin);
+ symbolTable.relateToOperator("atomicCounterMaxARB", EOpAtomicCounterMax);
+ symbolTable.relateToOperator("atomicCounterAndARB", EOpAtomicCounterAnd);
+ symbolTable.relateToOperator("atomicCounterOrARB", EOpAtomicCounterOr);
+ symbolTable.relateToOperator("atomicCounterXorARB", EOpAtomicCounterXor);
+ symbolTable.relateToOperator("atomicCounterExchangeARB", EOpAtomicCounterExchange);
+ symbolTable.relateToOperator("atomicCounterCompSwapARB", EOpAtomicCounterCompSwap);
+ }
+
if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("atomicCounterAdd", EOpAtomicCounterAdd);
symbolTable.relateToOperator("atomicCounterSubtract", EOpAtomicCounterSubtract);
@@ -9668,6 +9723,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
case EShLangMiss:
if (profile != EEsProfile && version >= 460) {
symbolTable.relateToOperator("traceNV", EOpTraceNV);
+ symbolTable.relateToOperator("traceRayMotionNV", EOpTraceRayMotionNV);
symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR);
symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV);
symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR);
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
index 02784459696..1283f449392 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Intermediate.cpp
@@ -416,20 +416,24 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
// TODO: but, did this bypass constant folding?
//
switch (op) {
- case EOpConstructInt8:
- case EOpConstructUint8:
- case EOpConstructInt16:
- case EOpConstructUint16:
- case EOpConstructInt:
- case EOpConstructUint:
- case EOpConstructInt64:
- case EOpConstructUint64:
- case EOpConstructBool:
- case EOpConstructFloat:
- case EOpConstructDouble:
- case EOpConstructFloat16:
- return child;
- default: break; // some compilers want this
+ case EOpConstructInt8:
+ case EOpConstructUint8:
+ case EOpConstructInt16:
+ case EOpConstructUint16:
+ case EOpConstructInt:
+ case EOpConstructUint:
+ case EOpConstructInt64:
+ case EOpConstructUint64:
+ case EOpConstructBool:
+ case EOpConstructFloat:
+ case EOpConstructDouble:
+ case EOpConstructFloat16: {
+ TIntermUnary* unary_node = child->getAsUnaryNode();
+ if (unary_node != nullptr)
+ unary_node->updatePrecision();
+ return child;
+ }
+ default: break; // some compilers want this
}
//
@@ -3778,6 +3782,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node)
// Propagate precision qualifiers *up* from children to parent, and then
// back *down* again to the children's subtrees.
+void TIntermAggregate::updatePrecision()
+{
+ if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
+ getBasicType() == EbtFloat || getBasicType() == EbtFloat16) {
+ TPrecisionQualifier maxPrecision = EpqNone;
+ TIntermSequence operands = getSequence();
+ for (unsigned int i = 0; i < operands.size(); ++i) {
+ TIntermTyped* typedNode = operands[i]->getAsTyped();
+ assert(typedNode);
+ maxPrecision = std::max(maxPrecision, typedNode->getQualifier().precision);
+ }
+ getQualifier().precision = maxPrecision;
+ for (unsigned int i = 0; i < operands.size(); ++i) {
+ TIntermTyped* typedNode = operands[i]->getAsTyped();
+ assert(typedNode);
+ typedNode->propagatePrecision(maxPrecision);
+ }
+ }
+}
+
+// Propagate precision qualifiers *up* from children to parent, and then
+// back *down* again to the children's subtrees.
void TIntermBinary::updatePrecision()
{
if (getBasicType() == EbtInt || getBasicType() == EbtUint ||
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp
index 02cca409e1e..1da50d62f93 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp
@@ -622,6 +622,19 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
+ // Check for declarations of this default uniform that already exist due to other compilation units.
+ TSymbol* symbol = symbolTable.find(memberName);
+ if (symbol) {
+ if (memberType != symbol->getType()) {
+ TString err;
+ err += "\"" + memberType.getCompleteString() + "\"";
+ err += " versus ";
+ err += "\"" + symbol->getType().getCompleteString() + "\"";
+ error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
+ }
+ return;
+ }
+
// Add the requested member as a member to the global block.
TType* type = new TType;
type->shallowCopy(memberType);
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
index 35a53e425d5..b2b187b4fd4 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp
@@ -2308,6 +2308,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
break;
+ case EOpTraceRayMotionNV:
+ if (!(*argp)[11]->getAsConstantUnion())
+ error(loc, "argument must be compile-time constant", "payload number", "a");
+ break;
case EOpTraceKHR:
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
@@ -7687,7 +7691,13 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
return nullptr;
}
- return intermediate.setAggregateOperator(aggrNode, op, type, loc);
+ TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
+
+ TIntermAggregate *agg_node = ret_node->getAsAggregate();
+ if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))
+ agg_node->updatePrecision();
+
+ return ret_node;
}
// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h
index de448846530..442741d6d40 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.h
@@ -241,7 +241,7 @@ protected:
// override this to set the language-specific name
virtual const char* getAtomicCounterBlockName() const { return ""; }
virtual void setAtomicCounterBlockDefaults(TType&) const {}
- virtual void setInvariant(const TSourceLoc& loc, const char* builtin) {}
+ virtual void setInvariant(const TSourceLoc&, const char*) {}
virtual void finalizeAtomicCounterBlockLayout(TVariable&) {}
bool isAtomicCounterBlock(const TSymbol& symbol) {
const TVariable* var = symbol.getAsVariable();
@@ -472,7 +472,7 @@ public:
// Determine loop control from attributes
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
// Function attributes
- void handleFunctionAttributes(const TSourceLoc&, const TAttributes&, TFunction*);
+ void handleFunctionAttributes(const TSourceLoc&, const TAttributes&);
// GL_EXT_spirv_intrinsics
TSpirvRequirement* makeSpirvRequirement(const TSourceLoc& loc, const TString& name,
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp
index 747b43666d1..5b7e27fa26f 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.cpp
@@ -279,8 +279,14 @@ TFunction::~TFunction()
//
TSymbolTableLevel::~TSymbolTableLevel()
{
- for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
- delete (*it).second;
+ for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+ const TString& name = it->first;
+ auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+ [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+ if (retargetIter == retargetedSymbols.end())
+ delete (*it).second;
+ }
+
delete [] defaultPrecision;
}
@@ -418,6 +424,15 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
symTableLevel->anonId = anonId;
symTableLevel->thisLevel = thisLevel;
+ symTableLevel->retargetedSymbols.clear();
+ for (auto &s : retargetedSymbols) {
+ // Extra constructions to make sure they use the correct allocator pool
+ TString newFrom;
+ newFrom = s.first;
+ TString newTo;
+ newTo = s.second;
+ symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
+ }
std::vector<bool> containerCopied(anonId, false);
tLevel::const_iterator iter;
for (iter = level.begin(); iter != level.end(); ++iter) {
@@ -433,8 +448,25 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
symTableLevel->insert(*container, false);
containerCopied[anon->getAnonId()] = true;
}
- } else
+ } else {
+ const TString& name = iter->first;
+ auto retargetIter = std::find_if(retargetedSymbols.begin(), retargetedSymbols.end(),
+ [&name](const std::pair<TString, TString>& i) { return i.first == name; });
+ if (retargetIter != retargetedSymbols.end())
+ continue;
symTableLevel->insert(*iter->second->clone(), false);
+ }
+ }
+ // Now point retargeted symbols to the newly created versions of them
+ for (auto &s : retargetedSymbols) {
+ TSymbol* sym = symTableLevel->find(s.second);
+ if (!sym)
+ continue;
+
+ // Need to declare and assign so newS is using the correct pool allocator
+ TString newS;
+ newS = s.first;
+ symTableLevel->insert(newS, sym);
}
return symTableLevel;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h
index 21960930738..720999a36a5 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/SymbolTable.h
@@ -413,13 +413,20 @@ public:
TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
~TSymbolTableLevel();
- bool insert(TSymbol& symbol, bool separateNameSpaces)
+ bool insert(const TString& name, TSymbol* symbol) {
+ return level.insert(tLevelPair(name, symbol)).second;
+ }
+
+ bool insert(TSymbol& symbol, bool separateNameSpaces, const TString& forcedKeyName = TString())
{
//
// returning true means symbol was added to the table with no semantic errors
//
const TString& name = symbol.getName();
- if (name == "") {
+ if (forcedKeyName.length()) {
+ return level.insert(tLevelPair(forcedKeyName, &symbol)).second;
+ }
+ else if (name == "") {
symbol.getAsVariable()->setAnonId(anonId++);
// An empty name means an anonymous container, exposing its members to the external scope.
// Give it a name and insert its members in the symbol table, pointing to the container.
@@ -471,6 +478,16 @@ public:
return true;
}
+ void retargetSymbol(const TString& from, const TString& to) {
+ tLevel::const_iterator fromIt = level.find(from);
+ tLevel::const_iterator toIt = level.find(to);
+ if (fromIt == level.end() || toIt == level.end())
+ return;
+ delete fromIt->second;
+ level[from] = toIt->second;
+ retargetedSymbols.push_back({from, to});
+ }
+
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
@@ -583,6 +600,8 @@ protected:
tLevel level; // named mappings
TPrecisionQualifier *defaultPrecision;
+ // pair<FromName, ToName>
+ TVector<std::pair<TString, TString>> retargetedSymbols;
int anonId;
bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
// that are supposed to see anonymous access to member variables.
@@ -788,6 +807,12 @@ public:
return symbol;
}
+ void retargetSymbol(const TString& from, const TString& to) {
+ int level = currentLevel();
+ table[level]->retargetSymbol(from, to);
+ }
+
+
// Find of a symbol that returns how many layers deep of nested
// structures-with-member-functions ('this' scopes) deep the symbol was
// found in.
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp
index 2698dd91777..097ee845529 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp
@@ -165,7 +165,9 @@ void TParseVersions::initializeExtensionBehavior()
EShTargetLanguageVersion minSpvVersion;
} extensionData;
- const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4} };
+ const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4},
+ {E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}
+ };
for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) {
// Add only extensions which require > spv1.0 to save space in map
@@ -198,6 +200,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
+ extensionBehavior[E_GL_ARB_shader_atomic_counter_ops] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
extensionBehavior[E_GL_ARB_shader_group_vote] = EBhDisable;
extensionBehavior[E_GL_ARB_derivative_control] = EBhDisable;
@@ -281,6 +284,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_shader_subgroup_partitioned] = EBhDisable;
extensionBehavior[E_GL_NV_shading_rate_image] = EBhDisable;
extensionBehavior[E_GL_NV_ray_tracing] = EBhDisable;
+ extensionBehavior[E_GL_NV_ray_tracing_motion_blur] = EBhDisable;
extensionBehavior[E_GL_NV_fragment_shader_barycentric] = EBhDisable;
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
@@ -518,6 +522,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_subgroup_partitioned 1\n"
"#define GL_NV_shading_rate_image 1\n"
"#define GL_NV_ray_tracing 1\n"
+ "#define GL_NV_ray_tracing_motion_blur 1\n"
"#define GL_NV_fragment_shader_barycentric 1\n"
"#define GL_NV_compute_shader_derivatives 1\n"
"#define GL_NV_shader_texture_footprint 1\n"
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h
index 2e8cc29893c..949a7a17398 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h
@@ -136,6 +136,7 @@ const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attri
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
+const char* const E_GL_ARB_shader_atomic_counter_ops = "GL_ARB_shader_atomic_counter_ops";
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
const char* const E_GL_ARB_shader_group_vote = "GL_ARB_shader_group_vote";
const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_control";
@@ -247,6 +248,7 @@ const char* const E_GL_NV_shader_noperspective_interpolation = "GL_NV_shader_
const char* const E_GL_NV_shader_subgroup_partitioned = "GL_NV_shader_subgroup_partitioned";
const char* const E_GL_NV_shading_rate_image = "GL_NV_shading_rate_image";
const char* const E_GL_NV_ray_tracing = "GL_NV_ray_tracing";
+const char* const E_GL_NV_ray_tracing_motion_blur = "GL_NV_ray_tracing_motion_blur";
const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragment_shader_barycentric";
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp
index 8a92f6ae098..df7fdc2a60f 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/attribute.cpp
@@ -347,7 +347,7 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
//
// Function attributes
//
-void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes, TFunction* function)
+void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttributes& attributes)
{
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
if (it->size() > 0) {
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.m4 b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.m4
index 93041ce39e5..36265029722 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.m4
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.m4
@@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
+ parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+ parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
- parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
+ parseContext.handleFunctionAttributes($3.loc, *$1);
+ parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
+ parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
+ parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y
index b77f4617bef..ad483863419 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y
@@ -983,20 +983,20 @@ function_prototype
$$.function = $1;
$$.loc = $2.loc;
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($2.loc, *$3, $$.function);
+ parseContext.handleFunctionAttributes($2.loc, *$3);
}
| attribute function_declarator RIGHT_PAREN {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
+ parseContext.handleFunctionAttributes($3.loc, *$1);
}
| attribute function_declarator RIGHT_PAREN attribute {
$$.function = $2;
$$.loc = $3.loc;
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes($3.loc, *$1, $$.function);
- parseContext.handleFunctionAttributes($3.loc, *$4, $$.function);
+ parseContext.handleFunctionAttributes($3.loc, *$1);
+ parseContext.handleFunctionAttributes($3.loc, *$4);
}
;
@@ -3926,6 +3926,7 @@ iteration_statement_nonattributed
--parseContext.controlFlowNestingLevel;
}
| DO {
+ parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
@@ -3937,6 +3938,7 @@ iteration_statement_nonattributed
parseContext.boolCheck($8.loc, $6);
$$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.loc);
+ parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
index dba06aefefb..33b8a924171 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp
@@ -1197,15 +1197,15 @@ static const yytype_int16 yyrline[] =
3732, 3739, 3739, 3753, 3756, 3764, 3772, 3783, 3784, 3788,
3792, 3800, 3807, 3811, 3819, 3823, 3836, 3840, 3848, 3848,
3868, 3871, 3877, 3889, 3901, 3905, 3913, 3913, 3928, 3928,
- 3944, 3944, 3965, 3968, 3974, 3977, 3983, 3987, 3994, 3999,
- 4004, 4011, 4014, 4018, 4023, 4027, 4037, 4041, 4050, 4053,
- 4057, 4066, 4066, 4108, 4113, 4116, 4121, 4124, 4131, 4134,
- 4139, 4142, 4147, 4150, 4155, 4158, 4163, 4167, 4172, 4176,
- 4181, 4185, 4192, 4195, 4200, 4203, 4206, 4209, 4212, 4217,
- 4226, 4237, 4242, 4250, 4254, 4259, 4263, 4268, 4272, 4277,
- 4281, 4288, 4291, 4296, 4299, 4302, 4305, 4310, 4318, 4328,
- 4332, 4337, 4341, 4346, 4350, 4357, 4360, 4365, 4368, 4373,
- 4376, 4382, 4385, 4390, 4393
+ 3946, 3946, 3967, 3970, 3976, 3979, 3985, 3989, 3996, 4001,
+ 4006, 4013, 4016, 4020, 4025, 4029, 4039, 4043, 4052, 4055,
+ 4059, 4068, 4068, 4110, 4115, 4118, 4123, 4126, 4133, 4136,
+ 4141, 4144, 4149, 4152, 4157, 4160, 4165, 4169, 4174, 4178,
+ 4183, 4187, 4194, 4197, 4202, 4205, 4208, 4211, 4214, 4219,
+ 4228, 4239, 4244, 4252, 4256, 4261, 4265, 4270, 4274, 4279,
+ 4283, 4290, 4293, 4298, 4301, 4304, 4307, 4312, 4320, 4330,
+ 4334, 4339, 4343, 4348, 4352, 4359, 4362, 4367, 4370, 4375,
+ 4378, 4384, 4387, 4392, 4395
};
#endif
@@ -6204,7 +6204,7 @@ yyreduce:
(yyval.interm).function = (yyvsp[-2].interm.function);
(yyval.interm).loc = (yyvsp[-1].lex).loc;
parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes), (yyval.interm).function);
+ parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes));
}
#line 6210 "MachineIndependent/glslang_tab.cpp"
break;
@@ -6215,7 +6215,7 @@ yyreduce:
(yyval.interm).function = (yyvsp[-1].interm.function);
(yyval.interm).loc = (yyvsp[0].lex).loc;
parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes((yyvsp[0].lex).loc, *(yyvsp[-2].interm.attributes), (yyval.interm).function);
+ parseContext.handleFunctionAttributes((yyvsp[0].lex).loc, *(yyvsp[-2].interm.attributes));
}
#line 6221 "MachineIndependent/glslang_tab.cpp"
break;
@@ -6226,8 +6226,8 @@ yyreduce:
(yyval.interm).function = (yyvsp[-2].interm.function);
(yyval.interm).loc = (yyvsp[-1].lex).loc;
parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
- parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[-3].interm.attributes), (yyval.interm).function);
- parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes), (yyval.interm).function);
+ parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[-3].interm.attributes));
+ parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes));
}
#line 6233 "MachineIndependent/glslang_tab.cpp"
break;
@@ -11387,15 +11387,16 @@ yyreduce:
case 598: /* $@11: %empty */
#line 3928 "MachineIndependent/glslang.y"
{
+ parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
}
-#line 11395 "MachineIndependent/glslang_tab.cpp"
+#line 11396 "MachineIndependent/glslang_tab.cpp"
break;
case 599: /* iteration_statement_nonattributed: DO $@11 statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON */
-#line 3933 "MachineIndependent/glslang.y"
+#line 3934 "MachineIndependent/glslang.y"
{
if (! parseContext.limits.whileLoops)
parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", "");
@@ -11403,26 +11404,27 @@ yyreduce:
parseContext.boolCheck((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode));
(yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[-5].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, false, (yyvsp[-4].lex).loc);
+ parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
--parseContext.loopNestingLevel;
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
}
-#line 11411 "MachineIndependent/glslang_tab.cpp"
+#line 11413 "MachineIndependent/glslang_tab.cpp"
break;
case 600: /* $@12: %empty */
-#line 3944 "MachineIndependent/glslang.y"
+#line 3946 "MachineIndependent/glslang.y"
{
parseContext.symbolTable.push();
++parseContext.loopNestingLevel;
++parseContext.statementNestingLevel;
++parseContext.controlFlowNestingLevel;
}
-#line 11422 "MachineIndependent/glslang_tab.cpp"
+#line 11424 "MachineIndependent/glslang_tab.cpp"
break;
case 601: /* iteration_statement_nonattributed: FOR LEFT_PAREN $@12 for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope */
-#line 3950 "MachineIndependent/glslang.y"
+#line 3952 "MachineIndependent/glslang.y"
{
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc);
@@ -11435,81 +11437,81 @@ yyreduce:
--parseContext.statementNestingLevel;
--parseContext.controlFlowNestingLevel;
}
-#line 11439 "MachineIndependent/glslang_tab.cpp"
+#line 11441 "MachineIndependent/glslang_tab.cpp"
break;
case 602: /* for_init_statement: expression_statement */
-#line 3965 "MachineIndependent/glslang.y"
+#line 3967 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
-#line 11447 "MachineIndependent/glslang_tab.cpp"
+#line 11449 "MachineIndependent/glslang_tab.cpp"
break;
case 603: /* for_init_statement: declaration_statement */
-#line 3968 "MachineIndependent/glslang.y"
+#line 3970 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
-#line 11455 "MachineIndependent/glslang_tab.cpp"
+#line 11457 "MachineIndependent/glslang_tab.cpp"
break;
case 604: /* conditionopt: condition */
-#line 3974 "MachineIndependent/glslang.y"
+#line 3976 "MachineIndependent/glslang.y"
{
(yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode);
}
-#line 11463 "MachineIndependent/glslang_tab.cpp"
+#line 11465 "MachineIndependent/glslang_tab.cpp"
break;
case 605: /* conditionopt: %empty */
-#line 3977 "MachineIndependent/glslang.y"
+#line 3979 "MachineIndependent/glslang.y"
{
(yyval.interm.intermTypedNode) = 0;
}
-#line 11471 "MachineIndependent/glslang_tab.cpp"
+#line 11473 "MachineIndependent/glslang_tab.cpp"
break;
case 606: /* for_rest_statement: conditionopt SEMICOLON */
-#line 3983 "MachineIndependent/glslang.y"
+#line 3985 "MachineIndependent/glslang.y"
{
(yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode);
(yyval.interm.nodePair).node2 = 0;
}
-#line 11480 "MachineIndependent/glslang_tab.cpp"
+#line 11482 "MachineIndependent/glslang_tab.cpp"
break;
case 607: /* for_rest_statement: conditionopt SEMICOLON expression */
-#line 3987 "MachineIndependent/glslang.y"
+#line 3989 "MachineIndependent/glslang.y"
{
(yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode);
(yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode);
}
-#line 11489 "MachineIndependent/glslang_tab.cpp"
+#line 11491 "MachineIndependent/glslang_tab.cpp"
break;
case 608: /* jump_statement: CONTINUE SEMICOLON */
-#line 3994 "MachineIndependent/glslang.y"
+#line 3996 "MachineIndependent/glslang.y"
{
if (parseContext.loopNestingLevel <= 0)
parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", "");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc);
}
-#line 11499 "MachineIndependent/glslang_tab.cpp"
+#line 11501 "MachineIndependent/glslang_tab.cpp"
break;
case 609: /* jump_statement: BREAK SEMICOLON */
-#line 3999 "MachineIndependent/glslang.y"
+#line 4001 "MachineIndependent/glslang.y"
{
if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0)
parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", "");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc);
}
-#line 11509 "MachineIndependent/glslang_tab.cpp"
+#line 11511 "MachineIndependent/glslang_tab.cpp"
break;
case 610: /* jump_statement: RETURN SEMICOLON */
-#line 4004 "MachineIndependent/glslang.y"
+#line 4006 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc);
if (parseContext.currentFunctionType->getBasicType() != EbtVoid)
@@ -11517,101 +11519,101 @@ yyreduce:
if (parseContext.inMain)
parseContext.postEntryPointReturn = true;
}
-#line 11521 "MachineIndependent/glslang_tab.cpp"
+#line 11523 "MachineIndependent/glslang_tab.cpp"
break;
case 611: /* jump_statement: RETURN expression SEMICOLON */
-#line 4011 "MachineIndependent/glslang.y"
+#line 4013 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode));
}
-#line 11529 "MachineIndependent/glslang_tab.cpp"
+#line 11531 "MachineIndependent/glslang_tab.cpp"
break;
case 612: /* jump_statement: DISCARD SEMICOLON */
-#line 4014 "MachineIndependent/glslang.y"
+#line 4016 "MachineIndependent/glslang.y"
{
parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc);
}
-#line 11538 "MachineIndependent/glslang_tab.cpp"
+#line 11540 "MachineIndependent/glslang_tab.cpp"
break;
case 613: /* jump_statement: TERMINATE_INVOCATION SEMICOLON */
-#line 4018 "MachineIndependent/glslang.y"
+#line 4020 "MachineIndependent/glslang.y"
{
parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "terminateInvocation");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateInvocation, (yyvsp[-1].lex).loc);
}
-#line 11547 "MachineIndependent/glslang_tab.cpp"
+#line 11549 "MachineIndependent/glslang_tab.cpp"
break;
case 614: /* jump_statement: TERMINATE_RAY SEMICOLON */
-#line 4023 "MachineIndependent/glslang.y"
+#line 4025 "MachineIndependent/glslang.y"
{
parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "terminateRayEXT");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateRayKHR, (yyvsp[-1].lex).loc);
}
-#line 11556 "MachineIndependent/glslang_tab.cpp"
+#line 11558 "MachineIndependent/glslang_tab.cpp"
break;
case 615: /* jump_statement: IGNORE_INTERSECTION SEMICOLON */
-#line 4027 "MachineIndependent/glslang.y"
+#line 4029 "MachineIndependent/glslang.y"
{
parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "ignoreIntersectionEXT");
(yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, (yyvsp[-1].lex).loc);
}
-#line 11565 "MachineIndependent/glslang_tab.cpp"
+#line 11567 "MachineIndependent/glslang_tab.cpp"
break;
case 616: /* translation_unit: external_declaration */
-#line 4037 "MachineIndependent/glslang.y"
+#line 4039 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
parseContext.intermediate.setTreeRoot((yyval.interm.intermNode));
}
-#line 11574 "MachineIndependent/glslang_tab.cpp"
+#line 11576 "MachineIndependent/glslang_tab.cpp"
break;
case 617: /* translation_unit: translation_unit external_declaration */
-#line 4041 "MachineIndependent/glslang.y"
+#line 4043 "MachineIndependent/glslang.y"
{
if ((yyvsp[0].interm.intermNode) != nullptr) {
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode));
parseContext.intermediate.setTreeRoot((yyval.interm.intermNode));
}
}
-#line 11585 "MachineIndependent/glslang_tab.cpp"
+#line 11587 "MachineIndependent/glslang_tab.cpp"
break;
case 618: /* external_declaration: function_definition */
-#line 4050 "MachineIndependent/glslang.y"
+#line 4052 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
-#line 11593 "MachineIndependent/glslang_tab.cpp"
+#line 11595 "MachineIndependent/glslang_tab.cpp"
break;
case 619: /* external_declaration: declaration */
-#line 4053 "MachineIndependent/glslang.y"
+#line 4055 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = (yyvsp[0].interm.intermNode);
}
-#line 11601 "MachineIndependent/glslang_tab.cpp"
+#line 11603 "MachineIndependent/glslang_tab.cpp"
break;
case 620: /* external_declaration: SEMICOLON */
-#line 4057 "MachineIndependent/glslang.y"
+#line 4059 "MachineIndependent/glslang.y"
{
parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon");
parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon");
(yyval.interm.intermNode) = nullptr;
}
-#line 11611 "MachineIndependent/glslang_tab.cpp"
+#line 11613 "MachineIndependent/glslang_tab.cpp"
break;
case 621: /* $@13: %empty */
-#line 4066 "MachineIndependent/glslang.y"
+#line 4068 "MachineIndependent/glslang.y"
{
(yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */);
(yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function);
@@ -11624,11 +11626,11 @@ yyreduce:
++parseContext.statementNestingLevel;
}
}
-#line 11628 "MachineIndependent/glslang_tab.cpp"
+#line 11630 "MachineIndependent/glslang_tab.cpp"
break;
case 622: /* function_definition: function_prototype $@13 compound_statement_no_new_scope */
-#line 4078 "MachineIndependent/glslang.y"
+#line 4080 "MachineIndependent/glslang.y"
{
// May be best done as post process phase on intermediate code
if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue)
@@ -11655,228 +11657,228 @@ yyreduce:
--parseContext.statementNestingLevel;
}
}
-#line 11659 "MachineIndependent/glslang_tab.cpp"
+#line 11661 "MachineIndependent/glslang_tab.cpp"
break;
case 623: /* attribute: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET */
-#line 4108 "MachineIndependent/glslang.y"
+#line 4110 "MachineIndependent/glslang.y"
{
(yyval.interm.attributes) = (yyvsp[-2].interm.attributes);
}
-#line 11667 "MachineIndependent/glslang_tab.cpp"
+#line 11669 "MachineIndependent/glslang_tab.cpp"
break;
case 624: /* attribute_list: single_attribute */
-#line 4113 "MachineIndependent/glslang.y"
+#line 4115 "MachineIndependent/glslang.y"
{
(yyval.interm.attributes) = (yyvsp[0].interm.attributes);
}
-#line 11675 "MachineIndependent/glslang_tab.cpp"
+#line 11677 "MachineIndependent/glslang_tab.cpp"
break;
case 625: /* attribute_list: attribute_list COMMA single_attribute */
-#line 4116 "MachineIndependent/glslang.y"
+#line 4118 "MachineIndependent/glslang.y"
{
(yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes));
}
-#line 11683 "MachineIndependent/glslang_tab.cpp"
+#line 11685 "MachineIndependent/glslang_tab.cpp"
break;
case 626: /* single_attribute: IDENTIFIER */
-#line 4121 "MachineIndependent/glslang.y"
+#line 4123 "MachineIndependent/glslang.y"
{
(yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string);
}
-#line 11691 "MachineIndependent/glslang_tab.cpp"
+#line 11693 "MachineIndependent/glslang_tab.cpp"
break;
case 627: /* single_attribute: IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN */
-#line 4124 "MachineIndependent/glslang.y"
+#line 4126 "MachineIndependent/glslang.y"
{
(yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode));
}
-#line 11699 "MachineIndependent/glslang_tab.cpp"
+#line 11701 "MachineIndependent/glslang_tab.cpp"
break;
case 628: /* spirv_requirements_list: spirv_requirements_parameter */
-#line 4131 "MachineIndependent/glslang.y"
+#line 4133 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvReq) = (yyvsp[0].interm.spirvReq);
}
-#line 11707 "MachineIndependent/glslang_tab.cpp"
+#line 11709 "MachineIndependent/glslang_tab.cpp"
break;
case 629: /* spirv_requirements_list: spirv_requirements_list COMMA spirv_requirements_parameter */
-#line 4134 "MachineIndependent/glslang.y"
+#line 4136 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvReq) = parseContext.mergeSpirvRequirements((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvReq), (yyvsp[0].interm.spirvReq));
}
-#line 11715 "MachineIndependent/glslang_tab.cpp"
+#line 11717 "MachineIndependent/glslang_tab.cpp"
break;
case 630: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET */
-#line 4139 "MachineIndependent/glslang.y"
+#line 4141 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, (yyvsp[-1].interm.intermNode)->getAsAggregate(), nullptr);
}
-#line 11723 "MachineIndependent/glslang_tab.cpp"
+#line 11725 "MachineIndependent/glslang_tab.cpp"
break;
case 631: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET */
-#line 4142 "MachineIndependent/glslang.y"
+#line 4144 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, nullptr, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11731 "MachineIndependent/glslang_tab.cpp"
+#line 11733 "MachineIndependent/glslang_tab.cpp"
break;
case 632: /* spirv_extension_list: STRING_LITERAL */
-#line 4147 "MachineIndependent/glslang.y"
+#line 4149 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true));
}
-#line 11739 "MachineIndependent/glslang_tab.cpp"
+#line 11741 "MachineIndependent/glslang_tab.cpp"
break;
case 633: /* spirv_extension_list: spirv_extension_list COMMA STRING_LITERAL */
-#line 4150 "MachineIndependent/glslang.y"
+#line 4152 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true));
}
-#line 11747 "MachineIndependent/glslang_tab.cpp"
+#line 11749 "MachineIndependent/glslang_tab.cpp"
break;
case 634: /* spirv_capability_list: INTCONSTANT */
-#line 4155 "MachineIndependent/glslang.y"
+#line 4157 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true));
}
-#line 11755 "MachineIndependent/glslang_tab.cpp"
+#line 11757 "MachineIndependent/glslang_tab.cpp"
break;
case 635: /* spirv_capability_list: spirv_capability_list COMMA INTCONSTANT */
-#line 4158 "MachineIndependent/glslang.y"
+#line 4160 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true));
}
-#line 11763 "MachineIndependent/glslang_tab.cpp"
+#line 11765 "MachineIndependent/glslang_tab.cpp"
break;
case 636: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN */
-#line 4163 "MachineIndependent/glslang.y"
+#line 4165 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i);
(yyval.interm.intermNode) = 0;
}
-#line 11772 "MachineIndependent/glslang_tab.cpp"
+#line 11774 "MachineIndependent/glslang_tab.cpp"
break;
case 637: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */
-#line 4167 "MachineIndependent/glslang.y"
+#line 4169 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq));
parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i);
(yyval.interm.intermNode) = 0;
}
-#line 11782 "MachineIndependent/glslang_tab.cpp"
+#line 11784 "MachineIndependent/glslang_tab.cpp"
break;
case 638: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */
-#line 4172 "MachineIndependent/glslang.y"
+#line 4174 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
(yyval.interm.intermNode) = 0;
}
-#line 11791 "MachineIndependent/glslang_tab.cpp"
+#line 11793 "MachineIndependent/glslang_tab.cpp"
break;
case 639: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */
-#line 4176 "MachineIndependent/glslang.y"
+#line 4178 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
(yyval.interm.intermNode) = 0;
}
-#line 11801 "MachineIndependent/glslang_tab.cpp"
+#line 11803 "MachineIndependent/glslang_tab.cpp"
break;
case 640: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */
-#line 4181 "MachineIndependent/glslang.y"
+#line 4183 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
(yyval.interm.intermNode) = 0;
}
-#line 11810 "MachineIndependent/glslang_tab.cpp"
+#line 11812 "MachineIndependent/glslang_tab.cpp"
break;
case 641: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */
-#line 4185 "MachineIndependent/glslang.y"
+#line 4187 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
(yyval.interm.intermNode) = 0;
}
-#line 11820 "MachineIndependent/glslang_tab.cpp"
+#line 11822 "MachineIndependent/glslang_tab.cpp"
break;
case 642: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter */
-#line 4192 "MachineIndependent/glslang.y"
+#line 4194 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode));
}
-#line 11828 "MachineIndependent/glslang_tab.cpp"
+#line 11830 "MachineIndependent/glslang_tab.cpp"
break;
case 643: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter */
-#line 4195 "MachineIndependent/glslang.y"
+#line 4197 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode));
}
-#line 11836 "MachineIndependent/glslang_tab.cpp"
+#line 11838 "MachineIndependent/glslang_tab.cpp"
break;
case 644: /* spirv_execution_mode_parameter: FLOATCONSTANT */
-#line 4200 "MachineIndependent/glslang.y"
+#line 4202 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true);
}
-#line 11844 "MachineIndependent/glslang_tab.cpp"
+#line 11846 "MachineIndependent/glslang_tab.cpp"
break;
case 645: /* spirv_execution_mode_parameter: INTCONSTANT */
-#line 4203 "MachineIndependent/glslang.y"
+#line 4205 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true);
}
-#line 11852 "MachineIndependent/glslang_tab.cpp"
+#line 11854 "MachineIndependent/glslang_tab.cpp"
break;
case 646: /* spirv_execution_mode_parameter: UINTCONSTANT */
-#line 4206 "MachineIndependent/glslang.y"
+#line 4208 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true);
}
-#line 11860 "MachineIndependent/glslang_tab.cpp"
+#line 11862 "MachineIndependent/glslang_tab.cpp"
break;
case 647: /* spirv_execution_mode_parameter: BOOLCONSTANT */
-#line 4209 "MachineIndependent/glslang.y"
+#line 4211 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true);
}
-#line 11868 "MachineIndependent/glslang_tab.cpp"
+#line 11870 "MachineIndependent/glslang_tab.cpp"
break;
case 648: /* spirv_execution_mode_parameter: STRING_LITERAL */
-#line 4212 "MachineIndependent/glslang.y"
+#line 4214 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true);
}
-#line 11876 "MachineIndependent/glslang_tab.cpp"
+#line 11878 "MachineIndependent/glslang_tab.cpp"
break;
case 649: /* spirv_execution_mode_id_parameter_list: constant_expression */
-#line 4217 "MachineIndependent/glslang.y"
+#line 4219 "MachineIndependent/glslang.y"
{
if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat &&
(yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt &&
@@ -11886,11 +11888,11 @@ yyreduce:
parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), "");
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode));
}
-#line 11890 "MachineIndependent/glslang_tab.cpp"
+#line 11892 "MachineIndependent/glslang_tab.cpp"
break;
case 650: /* spirv_execution_mode_id_parameter_list: spirv_execution_mode_id_parameter_list COMMA constant_expression */
-#line 4226 "MachineIndependent/glslang.y"
+#line 4228 "MachineIndependent/glslang.y"
{
if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat &&
(yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt &&
@@ -11900,156 +11902,156 @@ yyreduce:
parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), "");
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode));
}
-#line 11904 "MachineIndependent/glslang_tab.cpp"
+#line 11906 "MachineIndependent/glslang_tab.cpp"
break;
case 651: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN */
-#line 4237 "MachineIndependent/glslang.y"
+#line 4239 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-3].lex).loc);
(yyval.interm.type).qualifier.storage = EvqSpirvStorageClass;
(yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i;
}
-#line 11914 "MachineIndependent/glslang_tab.cpp"
+#line 11916 "MachineIndependent/glslang_tab.cpp"
break;
case 652: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */
-#line 4242 "MachineIndependent/glslang.y"
+#line 4244 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc);
parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq));
(yyval.interm.type).qualifier.storage = EvqSpirvStorageClass;
(yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i;
}
-#line 11925 "MachineIndependent/glslang_tab.cpp"
+#line 11927 "MachineIndependent/glslang_tab.cpp"
break;
case 653: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN */
-#line 4250 "MachineIndependent/glslang.y"
+#line 4252 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-3].lex).loc);
(yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i);
}
-#line 11934 "MachineIndependent/glslang_tab.cpp"
+#line 11936 "MachineIndependent/glslang_tab.cpp"
break;
case 654: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */
-#line 4254 "MachineIndependent/glslang.y"
+#line 4256 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc);
parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq));
(yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i);
}
-#line 11944 "MachineIndependent/glslang_tab.cpp"
+#line 11946 "MachineIndependent/glslang_tab.cpp"
break;
case 655: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */
-#line 4259 "MachineIndependent/glslang.y"
+#line 4261 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc);
(yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11953 "MachineIndependent/glslang_tab.cpp"
+#line 11955 "MachineIndependent/glslang_tab.cpp"
break;
case 656: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */
-#line 4263 "MachineIndependent/glslang.y"
+#line 4265 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-7].lex).loc);
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
(yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11963 "MachineIndependent/glslang_tab.cpp"
+#line 11965 "MachineIndependent/glslang_tab.cpp"
break;
case 657: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */
-#line 4268 "MachineIndependent/glslang.y"
+#line 4270 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc);
(yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11972 "MachineIndependent/glslang_tab.cpp"
+#line 11974 "MachineIndependent/glslang_tab.cpp"
break;
case 658: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */
-#line 4272 "MachineIndependent/glslang.y"
+#line 4274 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-7].lex).loc);
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
(yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11982 "MachineIndependent/glslang_tab.cpp"
+#line 11984 "MachineIndependent/glslang_tab.cpp"
break;
case 659: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */
-#line 4277 "MachineIndependent/glslang.y"
+#line 4279 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc);
(yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 11991 "MachineIndependent/glslang_tab.cpp"
+#line 11993 "MachineIndependent/glslang_tab.cpp"
break;
case 660: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */
-#line 4281 "MachineIndependent/glslang.y"
+#line 4283 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-7].lex).loc);
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
(yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate());
}
-#line 12001 "MachineIndependent/glslang_tab.cpp"
+#line 12003 "MachineIndependent/glslang_tab.cpp"
break;
case 661: /* spirv_decorate_parameter_list: spirv_decorate_parameter */
-#line 4288 "MachineIndependent/glslang.y"
+#line 4290 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode));
}
-#line 12009 "MachineIndependent/glslang_tab.cpp"
+#line 12011 "MachineIndependent/glslang_tab.cpp"
break;
case 662: /* spirv_decorate_parameter_list: spirv_decorate_parameter_list COMMA spirv_decorate_parameter */
-#line 4291 "MachineIndependent/glslang.y"
+#line 4293 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode));
}
-#line 12017 "MachineIndependent/glslang_tab.cpp"
+#line 12019 "MachineIndependent/glslang_tab.cpp"
break;
case 663: /* spirv_decorate_parameter: FLOATCONSTANT */
-#line 4296 "MachineIndependent/glslang.y"
+#line 4298 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true);
}
-#line 12025 "MachineIndependent/glslang_tab.cpp"
+#line 12027 "MachineIndependent/glslang_tab.cpp"
break;
case 664: /* spirv_decorate_parameter: INTCONSTANT */
-#line 4299 "MachineIndependent/glslang.y"
+#line 4301 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true);
}
-#line 12033 "MachineIndependent/glslang_tab.cpp"
+#line 12035 "MachineIndependent/glslang_tab.cpp"
break;
case 665: /* spirv_decorate_parameter: UINTCONSTANT */
-#line 4302 "MachineIndependent/glslang.y"
+#line 4304 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true);
}
-#line 12041 "MachineIndependent/glslang_tab.cpp"
+#line 12043 "MachineIndependent/glslang_tab.cpp"
break;
case 666: /* spirv_decorate_parameter: BOOLCONSTANT */
-#line 4305 "MachineIndependent/glslang.y"
+#line 4307 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true);
}
-#line 12049 "MachineIndependent/glslang_tab.cpp"
+#line 12051 "MachineIndependent/glslang_tab.cpp"
break;
case 667: /* spirv_decorate_id_parameter_list: constant_expression */
-#line 4310 "MachineIndependent/glslang.y"
+#line 4312 "MachineIndependent/glslang.y"
{
if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat &&
(yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt &&
@@ -12058,11 +12060,11 @@ yyreduce:
parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), "");
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode));
}
-#line 12062 "MachineIndependent/glslang_tab.cpp"
+#line 12064 "MachineIndependent/glslang_tab.cpp"
break;
case 668: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter_list COMMA constant_expression */
-#line 4318 "MachineIndependent/glslang.y"
+#line 4320 "MachineIndependent/glslang.y"
{
if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat &&
(yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt &&
@@ -12071,147 +12073,147 @@ yyreduce:
parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), "");
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode));
}
-#line 12075 "MachineIndependent/glslang_tab.cpp"
+#line 12077 "MachineIndependent/glslang_tab.cpp"
break;
case 669: /* spirv_decorate_string_parameter_list: STRING_LITERAL */
-#line 4328 "MachineIndependent/glslang.y"
+#line 4330 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(
parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true));
}
-#line 12084 "MachineIndependent/glslang_tab.cpp"
+#line 12086 "MachineIndependent/glslang_tab.cpp"
break;
case 670: /* spirv_decorate_string_parameter_list: spirv_decorate_string_parameter_list COMMA STRING_LITERAL */
-#line 4332 "MachineIndependent/glslang.y"
+#line 4334 "MachineIndependent/glslang.y"
{
(yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true));
}
-#line 12092 "MachineIndependent/glslang_tab.cpp"
+#line 12094 "MachineIndependent/glslang_tab.cpp"
break;
case 671: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */
-#line 4337 "MachineIndependent/glslang.y"
+#line 4339 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel());
(yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams));
}
-#line 12101 "MachineIndependent/glslang_tab.cpp"
+#line 12103 "MachineIndependent/glslang_tab.cpp"
break;
case 672: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */
-#line 4341 "MachineIndependent/glslang.y"
+#line 4343 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-7].lex).loc, parseContext.symbolTable.atGlobalLevel());
parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq));
(yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams));
}
-#line 12111 "MachineIndependent/glslang_tab.cpp"
+#line 12113 "MachineIndependent/glslang_tab.cpp"
break;
case 673: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */
-#line 4346 "MachineIndependent/glslang.y"
+#line 4348 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-3].lex).loc, parseContext.symbolTable.atGlobalLevel());
(yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst));
}
-#line 12120 "MachineIndependent/glslang_tab.cpp"
+#line 12122 "MachineIndependent/glslang_tab.cpp"
break;
case 674: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */
-#line 4350 "MachineIndependent/glslang.y"
+#line 4352 "MachineIndependent/glslang.y"
{
(yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel());
parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq));
(yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst));
}
-#line 12130 "MachineIndependent/glslang_tab.cpp"
+#line 12132 "MachineIndependent/glslang_tab.cpp"
break;
case 675: /* spirv_type_parameter_list: spirv_type_parameter */
-#line 4357 "MachineIndependent/glslang.y"
+#line 4359 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvTypeParams) = (yyvsp[0].interm.spirvTypeParams);
}
-#line 12138 "MachineIndependent/glslang_tab.cpp"
+#line 12140 "MachineIndependent/glslang_tab.cpp"
break;
case 676: /* spirv_type_parameter_list: spirv_type_parameter_list COMMA spirv_type_parameter */
-#line 4360 "MachineIndependent/glslang.y"
+#line 4362 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvTypeParams) = parseContext.mergeSpirvTypeParameters((yyvsp[-2].interm.spirvTypeParams), (yyvsp[0].interm.spirvTypeParams));
}
-#line 12146 "MachineIndependent/glslang_tab.cpp"
+#line 12148 "MachineIndependent/glslang_tab.cpp"
break;
case 677: /* spirv_type_parameter: constant_expression */
-#line 4365 "MachineIndependent/glslang.y"
+#line 4367 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)->getAsConstantUnion());
}
-#line 12154 "MachineIndependent/glslang_tab.cpp"
+#line 12156 "MachineIndependent/glslang_tab.cpp"
break;
case 678: /* spirv_type_parameter: type_specifier */
-#line 4368 "MachineIndependent/glslang.y"
+#line 4370 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.type));
}
-#line 12162 "MachineIndependent/glslang_tab.cpp"
+#line 12164 "MachineIndependent/glslang_tab.cpp"
break;
case 679: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */
-#line 4373 "MachineIndependent/glslang.y"
+#line 4375 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst);
}
-#line 12170 "MachineIndependent/glslang_tab.cpp"
+#line 12172 "MachineIndependent/glslang_tab.cpp"
break;
case 680: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */
-#line 4376 "MachineIndependent/glslang.y"
+#line 4378 "MachineIndependent/glslang.y"
{
parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq));
(yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst);
}
-#line 12179 "MachineIndependent/glslang_tab.cpp"
+#line 12181 "MachineIndependent/glslang_tab.cpp"
break;
case 681: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_id */
-#line 4382 "MachineIndependent/glslang.y"
+#line 4384 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvInst) = (yyvsp[0].interm.spirvInst);
}
-#line 12187 "MachineIndependent/glslang_tab.cpp"
+#line 12189 "MachineIndependent/glslang_tab.cpp"
break;
case 682: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id */
-#line 4385 "MachineIndependent/glslang.y"
+#line 4387 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvInst) = parseContext.mergeSpirvInstruction((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvInst), (yyvsp[0].interm.spirvInst));
}
-#line 12195 "MachineIndependent/glslang_tab.cpp"
+#line 12197 "MachineIndependent/glslang_tab.cpp"
break;
case 683: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL STRING_LITERAL */
-#line 4390 "MachineIndependent/glslang.y"
+#line 4392 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, *(yyvsp[0].lex).string);
}
-#line 12203 "MachineIndependent/glslang_tab.cpp"
+#line 12205 "MachineIndependent/glslang_tab.cpp"
break;
case 684: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */
-#line 4393 "MachineIndependent/glslang.y"
+#line 4395 "MachineIndependent/glslang.y"
{
(yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[0].lex).i);
}
-#line 12211 "MachineIndependent/glslang_tab.cpp"
+#line 12213 "MachineIndependent/glslang_tab.cpp"
break;
-#line 12215 "MachineIndependent/glslang_tab.cpp"
+#line 12217 "MachineIndependent/glslang_tab.cpp"
default: break;
}
@@ -12436,5 +12438,5 @@ yyreturn:
return yyresult;
}
-#line 4398 "MachineIndependent/glslang.y"
+#line 4400 "MachineIndependent/glslang.y"
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp
index 105adc480e9..a0fade16c03 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/intermOut.cpp
@@ -1089,6 +1089,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
case EOpTraceNV: out.debug << "traceNV"; break;
+ case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break;
case EOpTraceKHR: out.debug << "traceRayKHR"; break;
case EOpReportIntersection: out.debug << "reportIntersectionNV"; break;
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
index 7e12864f361..3486ea6d05b 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
@@ -1633,6 +1633,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
});
resolver->endResolve(EShLangCount);
+ if (autoPushConstantBlockName.length()) {
+ bool upgraded = false;
+ for (size_t stage = 0; stage < EShLangCount; stage++) {
+ if (intermediates[stage] != nullptr) {
+ TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
+ auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
+ if (at == pUniformVarMap[stage]->end())
+ continue;
+ TQualifier& qualifier = at->second.symbol->getQualifier();
+ if (!qualifier.isUniform())
+ continue;
+ TType& t = at->second.symbol->getWritableType();
+ int size, stride;
+ TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
+ qualifier.layoutMatrix == ElmRowMajor);
+ if (size <= int(autoPushConstantMaxSize)) {
+ qualifier.setBlockStorage(EbsPushConstant);
+ qualifier.layoutPacking = autoPushConstantBlockPacking;
+ upgraded = true;
+ }
+ }
+ }
+ // If it's been upgraded to push_constant, then remove it from the uniformVector
+ // so it doesn't get a set/binding assigned to it.
+ if (upgraded) {
+ auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
+ [this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
+ if (at != uniformVector.end())
+ uniformVector.erase(at);
+ }
+ }
for (size_t stage = 0; stage < EShLangCount; stage++) {
if (intermediates[stage] != nullptr) {
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.h b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.h
index 07357c2ef43..843ea73c011 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.h
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.h
@@ -291,7 +291,7 @@ public:
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
};
-// I/O mapper for OpenGL
+// I/O mapper for GLSL
class TGlslIoMapper : public TIoMapper {
public:
TGlslIoMapper() {
@@ -301,6 +301,8 @@ public:
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
profile = ENoProfile;
version = 0;
+ autoPushConstantMaxSize = 128;
+ autoPushConstantBlockPacking = ElpStd430;
}
virtual ~TGlslIoMapper() {
for (size_t stage = 0; stage < EShLangCount; stage++) {
@@ -320,6 +322,13 @@ public:
intermediates[stage] = nullptr;
}
}
+ // If set, the uniform block with the given name will be changed to be backed by
+ // push_constant if it's size is <= maxSize
+ void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
+ autoPushConstantBlockName = name;
+ autoPushConstantMaxSize = maxSize;
+ autoPushConstantBlockPacking = packing;
+ }
// grow the reflection stage by stage
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
bool doMap(TIoMapResolver*, TInfoSink&) override;
@@ -329,6 +338,11 @@ public:
bool hadError = false;
EProfile profile;
int version;
+
+private:
+ TString autoPushConstantBlockName;
+ unsigned int autoPushConstantMaxSize;
+ TLayoutPacking autoPushConstantBlockPacking;
};
} // end namespace glslang
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
index 9656e2e7e0b..4edd2a9052c 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp
@@ -1934,7 +1934,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
}
// rule 9
- if (type.getBasicType() == EbtStruct) {
+ if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
const TTypeList& memberList = *type.getStruct();
size = 0;
@@ -2159,8 +2159,9 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
return type.isArray() &&
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
- (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut &&
+ (language == EShLangTessControl && (type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut) &&
! type.getQualifier().patch) ||
+ (language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn &&
type.getQualifier().pervertexNV) ||
(language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut &&
diff --git a/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_beta.h b/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_beta.h
index c615bb35f9a..f67fab36a65 100644
--- a/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_beta.h
+++ b/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_beta.h
@@ -22,7 +22,7 @@ extern "C" {
#define VK_KHR_video_queue 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionKHR)
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkVideoSessionParametersKHR)
-#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 1
+#define VK_KHR_VIDEO_QUEUE_SPEC_VERSION 2
#define VK_KHR_VIDEO_QUEUE_EXTENSION_NAME "VK_KHR_video_queue"
typedef enum VkQueryResultStatusKHR {
@@ -66,12 +66,12 @@ typedef enum VkVideoComponentBitDepthFlagBitsKHR {
} VkVideoComponentBitDepthFlagBitsKHR;
typedef VkFlags VkVideoComponentBitDepthFlagsKHR;
-typedef enum VkVideoCapabilitiesFlagBitsKHR {
- VK_VIDEO_CAPABILITIES_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
- VK_VIDEO_CAPABILITIES_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002,
- VK_VIDEO_CAPABILITIES_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
-} VkVideoCapabilitiesFlagBitsKHR;
-typedef VkFlags VkVideoCapabilitiesFlagsKHR;
+typedef enum VkVideoCapabilityFlagBitsKHR {
+ VK_VIDEO_CAPABILITY_PROTECTED_CONTENT_BIT_KHR = 0x00000001,
+ VK_VIDEO_CAPABILITY_SEPARATE_REFERENCE_IMAGES_BIT_KHR = 0x00000002,
+ VK_VIDEO_CAPABILITY_FLAG_BITS_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkVideoCapabilityFlagBitsKHR;
+typedef VkFlags VkVideoCapabilityFlagsKHR;
typedef enum VkVideoSessionCreateFlagBitsKHR {
VK_VIDEO_SESSION_CREATE_DEFAULT_KHR = 0,
@@ -90,7 +90,6 @@ typedef enum VkVideoCodingControlFlagBitsKHR {
typedef VkFlags VkVideoCodingControlFlagsKHR;
typedef enum VkVideoCodingQualityPresetFlagBitsKHR {
- VK_VIDEO_CODING_QUALITY_PRESET_DEFAULT_BIT_KHR = 0,
VK_VIDEO_CODING_QUALITY_PRESET_NORMAL_BIT_KHR = 0x00000001,
VK_VIDEO_CODING_QUALITY_PRESET_POWER_BIT_KHR = 0x00000002,
VK_VIDEO_CODING_QUALITY_PRESET_QUALITY_BIT_KHR = 0x00000004,
@@ -120,16 +119,16 @@ typedef struct VkVideoProfilesKHR {
} VkVideoProfilesKHR;
typedef struct VkVideoCapabilitiesKHR {
- VkStructureType sType;
- void* pNext;
- VkVideoCapabilitiesFlagsKHR capabilityFlags;
- VkDeviceSize minBitstreamBufferOffsetAlignment;
- VkDeviceSize minBitstreamBufferSizeAlignment;
- VkExtent2D videoPictureExtentGranularity;
- VkExtent2D minExtent;
- VkExtent2D maxExtent;
- uint32_t maxReferencePicturesSlotsCount;
- uint32_t maxReferencePicturesActiveCount;
+ VkStructureType sType;
+ void* pNext;
+ VkVideoCapabilityFlagsKHR capabilityFlags;
+ VkDeviceSize minBitstreamBufferOffsetAlignment;
+ VkDeviceSize minBitstreamBufferSizeAlignment;
+ VkExtent2D videoPictureExtentGranularity;
+ VkExtent2D minExtent;
+ VkExtent2D maxExtent;
+ uint32_t maxReferencePicturesSlotsCount;
+ uint32_t maxReferencePicturesActiveCount;
} VkVideoCapabilitiesKHR;
typedef struct VkPhysicalDeviceVideoFormatInfoKHR {
@@ -433,10 +432,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdEncodeVideoKHR(
#define VK_EXT_video_encode_h264 1
#include "vk_video/vulkan_video_codec_h264std.h"
#include "vk_video/vulkan_video_codec_h264std_encode.h"
-#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 1
+#define VK_EXT_VIDEO_ENCODE_H264_SPEC_VERSION 2
#define VK_EXT_VIDEO_ENCODE_H264_EXTENSION_NAME "VK_EXT_video_encode_h264"
-typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT {
+typedef enum VkVideoEncodeH264CapabilityFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_CABAC_BIT_EXT = 0x00000001,
VK_VIDEO_ENCODE_H264_CAPABILITY_CAVLC_BIT_EXT = 0x00000002,
VK_VIDEO_ENCODE_H264_CAPABILITY_WEIGHTED_BI_PRED_IMPLICIT_BIT_EXT = 0x00000004,
@@ -448,9 +447,9 @@ typedef enum VkVideoEncodeH264CapabilitiesFlagBitsEXT {
VK_VIDEO_ENCODE_H264_CAPABILITY_DEBLOCKING_FILTER_PARTIAL_BIT_EXT = 0x00000100,
VK_VIDEO_ENCODE_H264_CAPABILITY_MULTIPLE_SLICE_PER_FRAME_BIT_EXT = 0x00000200,
VK_VIDEO_ENCODE_H264_CAPABILITY_EVENLY_DISTRIBUTED_SLICE_SIZE_BIT_EXT = 0x00000400,
- VK_VIDEO_ENCODE_H264_CAPABILITIES_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkVideoEncodeH264CapabilitiesFlagBitsEXT;
-typedef VkFlags VkVideoEncodeH264CapabilitiesFlagsEXT;
+ VK_VIDEO_ENCODE_H264_CAPABILITY_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkVideoEncodeH264CapabilityFlagBitsEXT;
+typedef VkFlags VkVideoEncodeH264CapabilityFlagsEXT;
typedef enum VkVideoEncodeH264InputModeFlagBitsEXT {
VK_VIDEO_ENCODE_H264_INPUT_MODE_FRAME_BIT_EXT = 0x00000001,
@@ -475,19 +474,19 @@ typedef enum VkVideoEncodeH264CreateFlagBitsEXT {
} VkVideoEncodeH264CreateFlagBitsEXT;
typedef VkFlags VkVideoEncodeH264CreateFlagsEXT;
typedef struct VkVideoEncodeH264CapabilitiesEXT {
- VkStructureType sType;
- const void* pNext;
- VkVideoEncodeH264CapabilitiesFlagsEXT flags;
- VkVideoEncodeH264InputModeFlagsEXT inputModeFlags;
- VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags;
- VkExtent2D minPictureSizeInMbs;
- VkExtent2D maxPictureSizeInMbs;
- VkExtent2D inputImageDataAlignment;
- uint8_t maxNumL0ReferenceForP;
- uint8_t maxNumL0ReferenceForB;
- uint8_t maxNumL1Reference;
- uint8_t qualityLevelCount;
- VkExtensionProperties stdExtensionVersion;
+ VkStructureType sType;
+ const void* pNext;
+ VkVideoEncodeH264CapabilityFlagsEXT flags;
+ VkVideoEncodeH264InputModeFlagsEXT inputModeFlags;
+ VkVideoEncodeH264OutputModeFlagsEXT outputModeFlags;
+ VkExtent2D minPictureSizeInMbs;
+ VkExtent2D maxPictureSizeInMbs;
+ VkExtent2D inputImageDataAlignment;
+ uint8_t maxNumL0ReferenceForP;
+ uint8_t maxNumL0ReferenceForB;
+ uint8_t maxNumL1Reference;
+ uint8_t qualityLevelCount;
+ VkExtensionProperties stdExtensionVersion;
} VkVideoEncodeH264CapabilitiesEXT;
typedef struct VkVideoEncodeH264SessionCreateInfoEXT {
@@ -567,22 +566,22 @@ typedef struct VkVideoEncodeH264ProfileEXT {
#define VK_EXT_video_decode_h264 1
#include "vk_video/vulkan_video_codec_h264std_decode.h"
-#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 1
+#define VK_EXT_VIDEO_DECODE_H264_SPEC_VERSION 3
#define VK_EXT_VIDEO_DECODE_H264_EXTENSION_NAME "VK_EXT_video_decode_h264"
-typedef enum VkVideoDecodeH264FieldLayoutFlagBitsEXT {
- VK_VIDEO_DECODE_H264_PROGRESSIVE_PICTURES_ONLY_EXT = 0,
- VK_VIDEO_DECODE_H264_FIELD_LAYOUT_LINE_INTERLACED_PLANE_BIT_EXT = 0x00000001,
- VK_VIDEO_DECODE_H264_FIELD_LAYOUT_SEPARATE_INTERLACED_PLANE_BIT_EXT = 0x00000002,
- VK_VIDEO_DECODE_H264_FIELD_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
-} VkVideoDecodeH264FieldLayoutFlagBitsEXT;
-typedef VkFlags VkVideoDecodeH264FieldLayoutFlagsEXT;
+typedef enum VkVideoDecodeH264PictureLayoutFlagBitsEXT {
+ VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_EXT = 0,
+ VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_INTERLEAVED_LINES_BIT_EXT = 0x00000001,
+ VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_INTERLACED_SEPARATE_PLANES_BIT_EXT = 0x00000002,
+ VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_FLAG_BITS_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkVideoDecodeH264PictureLayoutFlagBitsEXT;
+typedef VkFlags VkVideoDecodeH264PictureLayoutFlagsEXT;
typedef VkFlags VkVideoDecodeH264CreateFlagsEXT;
typedef struct VkVideoDecodeH264ProfileEXT {
- VkStructureType sType;
- const void* pNext;
- StdVideoH264ProfileIdc stdProfileIdc;
- VkVideoDecodeH264FieldLayoutFlagsEXT fieldLayout;
+ VkStructureType sType;
+ const void* pNext;
+ StdVideoH264ProfileIdc stdProfileIdc;
+ VkVideoDecodeH264PictureLayoutFlagsEXT pictureLayout;
} VkVideoDecodeH264ProfileEXT;
typedef struct VkVideoDecodeH264CapabilitiesEXT {
diff --git a/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h b/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h
index 8166e173fe6..4a595573f21 100644
--- a/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h
+++ b/3rdparty/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h
@@ -72,7 +72,7 @@ extern "C" {
#define VK_API_VERSION_1_0 VK_MAKE_API_VERSION(0, 1, 0, 0)// Patch version should always be set to 0
// Version of this file
-#define VK_HEADER_VERSION 185
+#define VK_HEADER_VERSION 193
// Complete version of this file
#define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 2, VK_HEADER_VERSION)
@@ -754,6 +754,8 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_GENERATED_COMMANDS_FEATURES_NV = 1000277007,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INHERITED_VIEWPORT_SCISSOR_FEATURES_NV = 1000278000,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_VIEWPORT_SCISSOR_INFO_NV = 1000278001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_FEATURES_KHR = 1000280000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_DOT_PRODUCT_PROPERTIES_KHR = 1000280001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT = 1000281000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT = 1000281001,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDER_PASS_TRANSFORM_INFO_QCOM = 1000282000,
@@ -824,6 +826,7 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_VERTEX_INPUT_BINDING_DESCRIPTION_2_EXT = 1000352001,
VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT = 1000352002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT = 1000353000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIMITIVE_TOPOLOGY_LIST_RESTART_FEATURES_EXT = 1000356000,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364000,
VK_STRUCTURE_TYPE_MEMORY_ZIRCON_HANDLE_PROPERTIES_FUCHSIA = 1000364001,
VK_STRUCTURE_TYPE_MEMORY_GET_ZIRCON_HANDLE_INFO_FUCHSIA = 1000364002,
@@ -843,6 +846,7 @@ typedef enum VkStructureType {
VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_EXT = 1000388001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_FEATURES_EXT = 1000392000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT = 1000392001,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT = 1000412000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
@@ -1706,13 +1710,15 @@ typedef enum VkAttachmentLoadOp {
VK_ATTACHMENT_LOAD_OP_LOAD = 0,
VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
+ VK_ATTACHMENT_LOAD_OP_NONE_EXT = 1000400000,
VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
} VkAttachmentLoadOp;
typedef enum VkAttachmentStoreOp {
VK_ATTACHMENT_STORE_OP_STORE = 0,
VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
- VK_ATTACHMENT_STORE_OP_NONE_QCOM = 1000301000,
+ VK_ATTACHMENT_STORE_OP_NONE_EXT = 1000301000,
+ VK_ATTACHMENT_STORE_OP_NONE_QCOM = VK_ATTACHMENT_STORE_OP_NONE_EXT,
VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
} VkAttachmentStoreOp;
@@ -2123,10 +2129,6 @@ typedef enum VkImageViewCreateFlagBits {
VK_IMAGE_VIEW_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkImageViewCreateFlagBits;
typedef VkFlags VkImageViewCreateFlags;
-
-typedef enum VkShaderModuleCreateFlagBits {
- VK_SHADER_MODULE_CREATE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
-} VkShaderModuleCreateFlagBits;
typedef VkFlags VkShaderModuleCreateFlags;
typedef enum VkPipelineCacheCreateFlagBits {
@@ -5282,6 +5284,10 @@ typedef enum VkDriverId {
VK_DRIVER_ID_MOLTENVK = 14,
VK_DRIVER_ID_COREAVI_PROPRIETARY = 15,
VK_DRIVER_ID_JUICE_PROPRIETARY = 16,
+ VK_DRIVER_ID_VERISILICON_PROPRIETARY = 17,
+ VK_DRIVER_ID_MESA_TURNIP = 18,
+ VK_DRIVER_ID_MESA_V3DV = 19,
+ VK_DRIVER_ID_MESA_PANVK = 20,
VK_DRIVER_ID_AMD_PROPRIETARY_KHR = VK_DRIVER_ID_AMD_PROPRIETARY,
VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR = VK_DRIVER_ID_AMD_OPEN_SOURCE,
VK_DRIVER_ID_MESA_RADV_KHR = VK_DRIVER_ID_MESA_RADV,
@@ -6563,8 +6569,10 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDispatchBaseKHR(
#define VK_KHR_maintenance1 1
-#define VK_KHR_MAINTENANCE1_SPEC_VERSION 2
-#define VK_KHR_MAINTENANCE1_EXTENSION_NAME "VK_KHR_maintenance1"
+#define VK_KHR_MAINTENANCE_1_SPEC_VERSION 2
+#define VK_KHR_MAINTENANCE_1_EXTENSION_NAME "VK_KHR_maintenance1"
+#define VK_KHR_MAINTENANCE1_SPEC_VERSION VK_KHR_MAINTENANCE_1_SPEC_VERSION
+#define VK_KHR_MAINTENANCE1_EXTENSION_NAME VK_KHR_MAINTENANCE_1_EXTENSION_NAME
typedef VkCommandPoolTrimFlags VkCommandPoolTrimFlagsKHR;
typedef void (VKAPI_PTR *PFN_vkTrimCommandPoolKHR)(VkDevice device, VkCommandPool commandPool, VkCommandPoolTrimFlags flags);
@@ -7144,8 +7152,10 @@ VKAPI_ATTR void VKAPI_CALL vkReleaseProfilingLockKHR(
#define VK_KHR_maintenance2 1
-#define VK_KHR_MAINTENANCE2_SPEC_VERSION 1
-#define VK_KHR_MAINTENANCE2_EXTENSION_NAME "VK_KHR_maintenance2"
+#define VK_KHR_MAINTENANCE_2_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE_2_EXTENSION_NAME "VK_KHR_maintenance2"
+#define VK_KHR_MAINTENANCE2_SPEC_VERSION VK_KHR_MAINTENANCE_2_SPEC_VERSION
+#define VK_KHR_MAINTENANCE2_EXTENSION_NAME VK_KHR_MAINTENANCE_2_EXTENSION_NAME
typedef VkPointClippingBehavior VkPointClippingBehaviorKHR;
typedef VkTessellationDomainOrigin VkTessellationDomainOriginKHR;
@@ -7398,8 +7408,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkBindImageMemory2KHR(
#define VK_KHR_maintenance3 1
-#define VK_KHR_MAINTENANCE3_SPEC_VERSION 1
-#define VK_KHR_MAINTENANCE3_EXTENSION_NAME "VK_KHR_maintenance3"
+#define VK_KHR_MAINTENANCE_3_SPEC_VERSION 1
+#define VK_KHR_MAINTENANCE_3_EXTENSION_NAME "VK_KHR_maintenance3"
+#define VK_KHR_MAINTENANCE3_SPEC_VERSION VK_KHR_MAINTENANCE_3_SPEC_VERSION
+#define VK_KHR_MAINTENANCE3_EXTENSION_NAME VK_KHR_MAINTENANCE_3_EXTENSION_NAME
typedef VkPhysicalDeviceMaintenance3Properties VkPhysicalDeviceMaintenance3PropertiesKHR;
typedef VkDescriptorSetLayoutSupport VkDescriptorSetLayoutSupportKHR;
@@ -7864,6 +7876,52 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPipelineExecutableInternalRepresentationsKHR
#endif
+#define VK_KHR_shader_integer_dot_product 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_SPEC_VERSION 1
+#define VK_KHR_SHADER_INTEGER_DOT_PRODUCT_EXTENSION_NAME "VK_KHR_shader_integer_dot_product"
+typedef struct VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 shaderIntegerDotProduct;
+} VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR;
+
+typedef struct VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 integerDotProduct8BitUnsignedAccelerated;
+ VkBool32 integerDotProduct8BitSignedAccelerated;
+ VkBool32 integerDotProduct8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProduct4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProduct16BitUnsignedAccelerated;
+ VkBool32 integerDotProduct16BitSignedAccelerated;
+ VkBool32 integerDotProduct16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct32BitUnsignedAccelerated;
+ VkBool32 integerDotProduct32BitSignedAccelerated;
+ VkBool32 integerDotProduct32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProduct64BitUnsignedAccelerated;
+ VkBool32 integerDotProduct64BitSignedAccelerated;
+ VkBool32 integerDotProduct64BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitUnsignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitSignedAccelerated;
+ VkBool32 integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated;
+} VkPhysicalDeviceShaderIntegerDotProductPropertiesKHR;
+
+
+
#define VK_KHR_pipeline_library 1
#define VK_KHR_PIPELINE_LIBRARY_SPEC_VERSION 1
#define VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME "VK_KHR_pipeline_library"
@@ -9253,8 +9311,10 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE(
#define VK_NV_viewport_array2 1
-#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION 1
-#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME "VK_NV_viewport_array2"
+#define VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION 1
+#define VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME "VK_NV_viewport_array2"
+#define VK_NV_VIEWPORT_ARRAY2_SPEC_VERSION VK_NV_VIEWPORT_ARRAY_2_SPEC_VERSION
+#define VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME VK_NV_VIEWPORT_ARRAY_2_EXTENSION_NAME
#define VK_NVX_multiview_per_view_attributes 1
@@ -10133,9 +10193,10 @@ typedef VkGeometryFlagBitsKHR VkGeometryFlagBitsNV;
typedef enum VkGeometryInstanceFlagBitsKHR {
VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR = 0x00000001,
- VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = 0x00000002,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR = 0x00000002,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR = 0x00000004,
VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR = 0x00000008,
+ VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR = VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR,
VK_GEOMETRY_INSTANCE_TRIANGLE_CULL_DISABLE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR,
VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_NV = VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR,
VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_NV = VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR,
@@ -11063,8 +11124,10 @@ typedef VkPhysicalDeviceScalarBlockLayoutFeatures VkPhysicalDeviceScalarBlockLay
#define VK_GOOGLE_hlsl_functionality1 1
-#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 1
-#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
+#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION 1
+#define VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
+#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION VK_GOOGLE_HLSL_FUNCTIONALITY_1_SPEC_VERSION
+#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME VK_GOOGLE_HLSL_FUNCTIONALITY_1_EXTENSION_NAME
#define VK_GOOGLE_decorate_string 1
@@ -12450,6 +12513,18 @@ typedef struct VkPhysicalDeviceDrmPropertiesEXT {
+#define VK_EXT_primitive_topology_list_restart 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_SPEC_VERSION 1
+#define VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME "VK_EXT_primitive_topology_list_restart"
+typedef struct VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 primitiveTopologyListRestart;
+ VkBool32 primitiveTopologyPatchListRestart;
+} VkPhysicalDevicePrimitiveTopologyListRestartFeaturesEXT;
+
+
+
#define VK_HUAWEI_subpass_shading 1
#define VK_HUAWEI_SUBPASS_SHADING_SPEC_VERSION 2
#define VK_HUAWEI_SUBPASS_SHADING_EXTENSION_NAME "VK_HUAWEI_subpass_shading"
@@ -12666,9 +12741,33 @@ VKAPI_ATTR void VKAPI_CALL vkCmdDrawMultiIndexedEXT(
#endif
+#define VK_EXT_load_store_op_none 1
+#define VK_EXT_LOAD_STORE_OP_NONE_SPEC_VERSION 1
+#define VK_EXT_LOAD_STORE_OP_NONE_EXTENSION_NAME "VK_EXT_load_store_op_none"
+
+
+#define VK_EXT_pageable_device_local_memory 1
+#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_SPEC_VERSION 1
+#define VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME "VK_EXT_pageable_device_local_memory"
+typedef struct VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 pageableDeviceLocalMemory;
+} VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT;
+
+typedef void (VKAPI_PTR *PFN_vkSetDeviceMemoryPriorityEXT)(VkDevice device, VkDeviceMemory memory, float priority);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR void VKAPI_CALL vkSetDeviceMemoryPriorityEXT(
+ VkDevice device,
+ VkDeviceMemory memory,
+ float priority);
+#endif
+
+
#define VK_KHR_acceleration_structure 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkAccelerationStructureKHR)
-#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 11
+#define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 12
#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure"
typedef enum VkBuildAccelerationStructureModeKHR {
diff --git a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp
index d053aac8ad2..519350611c4 100644
--- a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp
@@ -3282,6 +3282,10 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3
}
case OpArrayLength:
+ // Only result is a temporary.
+ notify_variable_access(args[1], current_block->self);
+ break;
+
case OpLine:
case OpNoLine:
// Uses literals, but cannot be a phi variable or temporary, so ignore.
diff --git a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp
index c5550ee59b2..2b19346d944 100644
--- a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp
@@ -4712,6 +4712,14 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop)
GLSL_BOP(UGreaterThanEqual, ">=");
GLSL_BOP(SGreaterThanEqual, ">=");
+ case OpSRem:
+ {
+ uint32_t op0 = cop.arguments[0];
+ uint32_t op1 = cop.arguments[1];
+ return join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", "(",
+ to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), ")");
+ }
+
case OpSelect:
{
if (cop.arguments.size() < 3)
@@ -8047,7 +8055,11 @@ string CompilerGLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i
{
// OpBitcast can deal with pointers.
if (out_type.pointer || in_type.pointer)
+ {
+ if (out_type.vecsize == 2 || in_type.vecsize == 2)
+ require_extension_internal("GL_EXT_buffer_reference_uvec2");
return type_to_glsl(out_type);
+ }
if (out_type.basetype == in_type.basetype)
return "";
@@ -12611,6 +12623,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (type.storage != StorageClassPhysicalStorageBufferEXT)
SPIRV_CROSS_THROW("Only StorageClassPhysicalStorageBufferEXT is supported by OpConvertUToPtr.");
+ auto &in_type = expression_type(ops[2]);
+ if (in_type.vecsize == 2)
+ require_extension_internal("GL_EXT_buffer_reference_uvec2");
+
auto op = type_to_glsl(type);
emit_unary_func_op(ops[0], ops[1], ops[2], op.c_str());
break;
@@ -12623,6 +12639,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction)
if (ptr_type.storage != StorageClassPhysicalStorageBufferEXT)
SPIRV_CROSS_THROW("Only StorageClassPhysicalStorageBufferEXT is supported by OpConvertPtrToU.");
+ if (type.vecsize == 2)
+ require_extension_internal("GL_EXT_buffer_reference_uvec2");
+
auto op = type_to_glsl(type);
emit_unary_func_op(ops[0], ops[1], ops[2], op.c_str());
break;
@@ -14974,26 +14993,30 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
}
// Might still have to flush phi variables if we branch from loop header directly to merge target.
- if (flush_phi_required(block.self, block.next_block))
+ // This is supposed to emit all cases where we branch from header to merge block directly.
+ // There are two main scenarios where cannot rely on default fallthrough.
+ // - There is an explicit default: label already.
+ // In this case, literals_to_merge need to form their own "default" case, so that we avoid executing that block.
+ // - Header -> Merge requires flushing PHI. In this case, we need to collect all cases and flush PHI there.
+ bool header_merge_requires_phi = flush_phi_required(block.self, block.next_block);
+ bool need_fallthrough_block = block.default_block == block.next_block || !literals_to_merge.empty();
+ if ((header_merge_requires_phi && need_fallthrough_block) || !literals_to_merge.empty())
{
- if (block.default_block == block.next_block || !literals_to_merge.empty())
- {
- for (auto &case_literal : literals_to_merge)
- statement("case ", to_case_label(case_literal, unsigned_case), label_suffix, ":");
+ for (auto &case_literal : literals_to_merge)
+ statement("case ", to_case_label(case_literal, unsigned_case), label_suffix, ":");
- if (block.default_block == block.next_block)
- {
- if (is_legacy_es())
- statement("else");
- else
- statement("default:");
- }
-
- begin_scope();
- flush_phi(block.self, block.next_block);
- statement("break;");
- end_scope();
+ if (block.default_block == block.next_block)
+ {
+ if (is_legacy_es())
+ statement("else");
+ else
+ statement("default:");
}
+
+ begin_scope();
+ flush_phi(block.self, block.next_block);
+ statement("break;");
+ end_scope();
}
if (degenerate_switch && !is_legacy_es())
@@ -15061,8 +15084,11 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block)
break;
}
+ // If the Kill is terminating a block with a (probably synthetic) return value, emit a return value statement.
case SPIRBlock::Kill:
statement(backend.discard_literal, ";");
+ if (block.return_value)
+ statement("return ", to_expression(block.return_value), ";");
break;
case SPIRBlock::Unreachable:
diff --git a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp
index 83d4d72b663..d9594d30424 100644
--- a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp
@@ -386,7 +386,7 @@ protected:
virtual void emit_struct_padding_target(const SPIRType &type);
virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0);
std::string constant_expression(const SPIRConstant &c);
- std::string constant_op_expression(const SPIRConstantOp &cop);
+ virtual std::string constant_op_expression(const SPIRConstantOp &cop);
virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector);
virtual void emit_fixup();
virtual std::string variable_decl(const SPIRType &type, const std::string &name, uint32_t id = 0);
diff --git a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp
index 76c55652b77..2b1e0626312 100644
--- a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp
@@ -877,12 +877,36 @@ void CompilerMSL::build_implicit_builtins()
if (need_position)
{
// If we can get away with returning void from entry point, we don't need to care.
- // If there is at least one other stage output, we need to return [[position]].
- need_position = false;
+ // If there is at least one other stage output, we need to return [[position]],
+ // so we need to create one if it doesn't appear in the SPIR-V. Before adding the
+ // implicit variable, check if it actually exists already, but just has not been used
+ // or initialized, and if so, mark it as active, and do not create the implicit variable.
+ bool has_output = false;
ir.for_each_typed_id<SPIRVariable>([&](uint32_t, SPIRVariable &var) {
if (var.storage == StorageClassOutput && interface_variable_exists_in_entry_point(var.self))
- need_position = true;
+ {
+ has_output = true;
+
+ // Check if the var is the Position builtin
+ if (has_decoration(var.self, DecorationBuiltIn) && get_decoration(var.self, DecorationBuiltIn) == BuiltInPosition)
+ active_output_builtins.set(BuiltInPosition);
+
+ // If the var is a struct, check if any members is the Position builtin
+ auto &var_type = get_variable_element_type(var);
+ if (var_type.basetype == SPIRType::Struct)
+ {
+ auto mbr_cnt = var_type.member_types.size();
+ for (uint32_t mbr_idx = 0; mbr_idx < mbr_cnt; mbr_idx++)
+ {
+ auto builtin = BuiltInMax;
+ bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin);
+ if (is_builtin && builtin == BuiltInPosition)
+ active_output_builtins.set(BuiltInPosition);
+ }
+ }
+ }
});
+ need_position = has_output && !active_output_builtins.get(BuiltInPosition);
}
if (need_position)
@@ -3443,6 +3467,9 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
// Add the output interface struct as a local variable to the entry function.
// If the entry point should return the output struct, set the entry function
// to return the output interface struct, otherwise to return nothing.
+ // Watch out for the rare case where the terminator of the last entry point block is a
+ // Kill, instead of a Return. Based on SPIR-V's block-domination rules, we assume that
+ // any block that has a Kill will also have a terminating Return, except the last block.
// Indicate the output var requires early initialization.
bool ep_should_return_output = !get_is_rasterization_disabled();
uint32_t rtn_id = ep_should_return_output ? ib_var_id : 0;
@@ -3452,7 +3479,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch)
for (auto &blk_id : entry_func.blocks)
{
auto &blk = get<SPIRBlock>(blk_id);
- if (blk.terminator == SPIRBlock::Return)
+ if (blk.terminator == SPIRBlock::Return || (blk.terminator == SPIRBlock::Kill && blk_id == entry_func.blocks.back()))
blk.return_value = rtn_id;
}
vars_needing_early_declaration.push_back(ib_var_id);
@@ -4262,9 +4289,6 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp
// In this case, we just flip transpose states, and emit the store, a transpose must be in the RHS expression, if any.
if (is_matrix(type) && lhs_e && lhs_e->need_transpose)
{
- if (!rhs_e)
- SPIRV_CROSS_THROW("Need to transpose right-side expression of a store to row-major matrix, but it is "
- "not a SPIRExpression.");
lhs_e->need_transpose = false;
if (rhs_e && rhs_e->need_transpose)
@@ -4904,7 +4928,7 @@ void CompilerMSL::emit_custom_functions()
// "fadd" intrinsic support
case SPVFuncImplFAdd:
statement("template<typename T>");
- statement("T spvFAdd(T l, T r)");
+ statement("[[clang::optnone]] T spvFAdd(T l, T r)");
begin_scope();
statement("return fma(T(1), l, r);");
end_scope();
@@ -4914,7 +4938,7 @@ void CompilerMSL::emit_custom_functions()
// "fsub" intrinsic support
case SPVFuncImplFSub:
statement("template<typename T>");
- statement("T spvFSub(T l, T r)");
+ statement("[[clang::optnone]] T spvFSub(T l, T r)");
begin_scope();
statement("return fma(T(-1), r, l);");
end_scope();
@@ -4924,14 +4948,14 @@ void CompilerMSL::emit_custom_functions()
// "fmul' intrinsic support
case SPVFuncImplFMul:
statement("template<typename T>");
- statement("T spvFMul(T l, T r)");
+ statement("[[clang::optnone]] T spvFMul(T l, T r)");
begin_scope();
statement("return fma(l, r, T(0));");
end_scope();
statement("");
statement("template<typename T, int Cols, int Rows>");
- statement("vec<T, Cols> spvFMulVectorMatrix(vec<T, Rows> v, matrix<T, Cols, Rows> m)");
+ statement("[[clang::optnone]] vec<T, Cols> spvFMulVectorMatrix(vec<T, Rows> v, matrix<T, Cols, Rows> m)");
begin_scope();
statement("vec<T, Cols> res = vec<T, Cols>(0);");
statement("for (uint i = Rows; i > 0; --i)");
@@ -4948,7 +4972,7 @@ void CompilerMSL::emit_custom_functions()
statement("");
statement("template<typename T, int Cols, int Rows>");
- statement("vec<T, Rows> spvFMulMatrixVector(matrix<T, Cols, Rows> m, vec<T, Cols> v)");
+ statement("[[clang::optnone]] vec<T, Rows> spvFMulMatrixVector(matrix<T, Cols, Rows> m, vec<T, Cols> v)");
begin_scope();
statement("vec<T, Rows> res = vec<T, Rows>(0);");
statement("for (uint i = Cols; i > 0; --i)");
@@ -4960,8 +4984,7 @@ void CompilerMSL::emit_custom_functions()
statement("");
statement("template<typename T, int LCols, int LRows, int RCols, int RRows>");
- statement(
- "matrix<T, RCols, LRows> spvFMulMatrixMatrix(matrix<T, LCols, LRows> l, matrix<T, RCols, RRows> r)");
+ statement("[[clang::optnone]] matrix<T, RCols, LRows> spvFMulMatrixMatrix(matrix<T, LCols, LRows> l, matrix<T, RCols, RRows> r)");
begin_scope();
statement("matrix<T, RCols, LRows> res;");
statement("for (uint i = 0; i < RCols; i++)");
@@ -5695,8 +5718,9 @@ void CompilerMSL::emit_custom_functions()
case SPVFuncImplReflectScalar:
// Metal does not support scalar versions of these functions.
+ // Ensure fast-math is disabled to match Vulkan results.
statement("template<typename T>");
- statement("inline T spvReflect(T i, T n)");
+ statement("[[clang::optnone]] T spvReflect(T i, T n)");
begin_scope();
statement("return i - T(2) * i * n * n;");
end_scope();
@@ -8490,13 +8514,27 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r
// Special considerations for stage IO variables.
// If the variable is actually backed by non-user visible device storage, we use array templates for those.
+ //
+ // Another special consideration is given to thread local variables which happen to have Offset decorations
+ // applied to them. Block-like types do not use array templates, so we need to force POD path if we detect
+ // these scenarios. This check isn't perfect since it would be technically possible to mix and match these things,
+ // and for a fully correct solution we might have to track array template state through access chains as well,
+ // but for all reasonable use cases, this should suffice.
+ // This special case should also only apply to Function/Private storage classes.
+ // We should not check backing variable for temporaries.
auto *lhs_var = maybe_get_backing_variable(lhs_id);
if (lhs_var && lhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(lhs_var->storage))
lhs_is_array_template = true;
+ else if (lhs_var && (lhs_storage == StorageClassFunction || lhs_storage == StorageClassPrivate) &&
+ type_is_block_like(get<SPIRType>(lhs_var->basetype)))
+ lhs_is_array_template = false;
auto *rhs_var = maybe_get_backing_variable(rhs_id);
if (rhs_var && rhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(rhs_var->storage))
rhs_is_array_template = true;
+ else if (rhs_var && (rhs_storage == StorageClassFunction || rhs_storage == StorageClassPrivate) &&
+ type_is_block_like(get<SPIRType>(rhs_var->basetype)))
+ rhs_is_array_template = false;
// If threadgroup storage qualifiers are *not* used:
// Avoid spvCopy* wrapper functions; Otherwise, spvUnsafeArray<> template cannot be used with that storage qualifier.
@@ -8743,7 +8781,8 @@ const char *CompilerMSL::get_memory_order(uint32_t)
return "memory_order_relaxed";
}
-// Override for MSL-specific extension syntax instructions
+// Override for MSL-specific extension syntax instructions.
+// In some cases, deliberately select either the fast or precise versions of the MSL functions to match Vulkan math precision results.
void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t count)
{
auto op = static_cast<GLSLstd450>(eop);
@@ -8755,8 +8794,17 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
switch (op)
{
+ case GLSLstd450Sinh:
+ emit_unary_func_op(result_type, id, args[0], "fast::sinh");
+ break;
+ case GLSLstd450Cosh:
+ emit_unary_func_op(result_type, id, args[0], "fast::cosh");
+ break;
+ case GLSLstd450Tanh:
+ emit_unary_func_op(result_type, id, args[0], "precise::tanh");
+ break;
case GLSLstd450Atan2:
- emit_binary_func_op(result_type, id, args[0], args[1], "atan2");
+ emit_binary_func_op(result_type, id, args[0], args[1], "precise::atan2");
break;
case GLSLstd450InverseSqrt:
emit_unary_func_op(result_type, id, args[0], "rsqrt");
@@ -8980,25 +9028,20 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop,
break;
case GLSLstd450Length:
- // MSL does not support scalar versions here.
+ // MSL does not support scalar versions, so use abs().
if (expression_type(args[0]).vecsize == 1)
- {
- // Equivalent to abs().
emit_unary_func_op(result_type, id, args[0], "abs");
- }
else
CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
break;
case GLSLstd450Normalize:
// MSL does not support scalar versions here.
+ // Returns -1 or 1 for valid input, sign() does the job.
if (expression_type(args[0]).vecsize == 1)
- {
- // Returns -1 or 1 for valid input, sign() does the job.
emit_unary_func_op(result_type, id, args[0], "sign");
- }
else
- CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count);
+ emit_unary_func_op(result_type, id, args[0], "fast::normalize");
break;
case GLSLstd450Reflect:
@@ -10628,15 +10671,9 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
return "";
}
}
- uint32_t comp;
- uint32_t locn = get_member_location(type.self, index, &comp);
- if (locn != k_unknown_location)
- {
- if (comp != k_unknown_component)
- return string(" [[user(locn") + convert_to_string(locn) + "_" + convert_to_string(comp) + ")]]";
- else
- return string(" [[user(locn") + convert_to_string(locn) + ")]]";
- }
+ string loc_qual = member_location_attribute_qualifier(type, index);
+ if (!loc_qual.empty())
+ return join(" [[", loc_qual, "]]");
}
// Tessellation control function inputs
@@ -10750,24 +10787,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
}
}
else
- {
- uint32_t comp;
- uint32_t locn = get_member_location(type.self, index, &comp);
- if (locn != k_unknown_location)
- {
- // For user-defined attributes, this is fine. From Vulkan spec:
- // A user-defined output variable is considered to match an input variable in the subsequent stage if
- // the two variables are declared with the same Location and Component decoration and match in type
- // and decoration, except that interpolation decorations are not required to match. For the purposes
- // of interface matching, variables declared without a Component decoration are considered to have a
- // Component decoration of zero.
-
- if (comp != k_unknown_component && comp != 0)
- quals = string("user(locn") + convert_to_string(locn) + "_" + convert_to_string(comp) + ")";
- else
- quals = string("user(locn") + convert_to_string(locn) + ")";
- }
- }
+ quals = member_location_attribute_qualifier(type, index);
if (builtin == BuiltInBaryCoordNV || builtin == BuiltInBaryCoordNoPerspNV)
{
@@ -10899,6 +10919,30 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in
return "";
}
+// A user-defined output variable is considered to match an input variable in the subsequent
+// stage if the two variables are declared with the same Location and Component decoration and
+// match in type and decoration, except that interpolation decorations are not required to match.
+// For the purposes of interface matching, variables declared without a Component decoration are
+// considered to have a Component decoration of zero.
+string CompilerMSL::member_location_attribute_qualifier(const SPIRType &type, uint32_t index)
+{
+ string quals;
+ uint32_t comp;
+ uint32_t locn = get_member_location(type.self, index, &comp);
+ if (locn != k_unknown_location)
+ {
+ quals += "user(locn";
+ quals += convert_to_string(locn);
+ if (comp != k_unknown_component && comp != 0)
+ {
+ quals += "_";
+ quals += convert_to_string(comp);
+ }
+ quals += ")";
+ }
+ return quals;
+}
+
// Returns the location decoration of the member with the specified index in the specified type.
// If the location of the member has been explicitly set, that location is used. If not, this
// function assumes the members are ordered in their location order, and simply returns the
@@ -13292,6 +13336,38 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type)
}
}
+string CompilerMSL::constant_op_expression(const SPIRConstantOp &cop)
+{
+ auto &type = get<SPIRType>(cop.basetype);
+ string op;
+
+ switch (cop.opcode)
+ {
+ case OpQuantizeToF16:
+ switch (type.vecsize)
+ {
+ case 1:
+ op = "float(half(";
+ break;
+ case 2:
+ op = "float2(half2(";
+ break;
+ case 3:
+ op = "float3(half3(";
+ break;
+ case 4:
+ op = "float4(half4(";
+ break;
+ default:
+ SPIRV_CROSS_THROW("Illegal argument to OpSpecConstantOp QuantizeToF16.");
+ }
+ return join(op, to_expression(cop.arguments[0]), "))");
+
+ default:
+ return CompilerGLSL::constant_op_expression(cop);
+ }
+}
+
bool CompilerMSL::variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const
{
if (variable.storage == storage)
@@ -13880,18 +13956,21 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in
assert(out_type.basetype != SPIRType::Boolean);
assert(in_type.basetype != SPIRType::Boolean);
- bool integral_cast = type_is_integral(out_type) && type_is_integral(in_type);
- bool same_size_cast = out_type.width == in_type.width;
+ bool integral_cast = type_is_integral(out_type) && type_is_integral(in_type) && (out_type.vecsize == in_type.vecsize);
+ bool same_size_cast = (out_type.width * out_type.vecsize) == (in_type.width * in_type.vecsize);
- if (integral_cast && same_size_cast)
+ // Bitcasting can only be used between types of the same overall size.
+ // And always formally cast between integers, because it's trivial, and also
+ // because Metal can internally cast the results of some integer ops to a larger
+ // size (eg. short shift right becomes int), which means chaining integer ops
+ // together may introduce size variations that SPIR-V doesn't know about.
+ if (same_size_cast && !integral_cast)
{
- // Trivial bitcast case, casts between integers.
- return type_to_glsl(out_type);
+ return "as_type<" + type_to_glsl(out_type) + ">";
}
else
{
- // Fall back to the catch-all bitcast in MSL.
- return "as_type<" + type_to_glsl(out_type) + ">";
+ return type_to_glsl(out_type);
}
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp
index 1997127201c..9dc1a1a0370 100644
--- a/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp
@@ -734,6 +734,7 @@ protected:
// Allow Metal to use the array<T> template to make arrays a value type
std::string type_to_array_glsl(const SPIRType &type) override;
+ std::string constant_op_expression(const SPIRConstantOp &cop) override;
// Threadgroup arrays can't have a wrapper type
std::string variable_decl(const SPIRVariable &variable) override;
@@ -866,6 +867,7 @@ protected:
std::string builtin_type_decl(spv::BuiltIn builtin, uint32_t id = 0);
std::string built_in_func_arg(spv::BuiltIn builtin, bool prefix_comma);
std::string member_attribute_qualifier(const SPIRType &type, uint32_t index);
+ std::string member_location_attribute_qualifier(const SPIRType &type, uint32_t index);
std::string argument_decl(const SPIRFunction::Parameter &arg);
std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp);
uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0);
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/SPIRV-Headers.pc.in b/3rdparty/bgfx/3rdparty/spirv-headers/SPIRV-Headers.pc.in
new file mode 100644
index 00000000000..345f5f80403
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/SPIRV-Headers.pc.in
@@ -0,0 +1,9 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+
+Name: SPIRV-Headers
+Description: Header files from the SPIR-V registry
+Version: @CMAKE_PROJECT_VERSION@
+Requires:
+Libs:
+Cflags: -I${includedir}
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml
index 75cba89a74c..525c97ddc46 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml
@@ -69,7 +69,7 @@
<id value="16" vendor="X-LEGEND" tool="Mesa-IR/SPIR-V Translator" comment="Contact Metora Wang, github:metora/MesaGLSLCompiler"/>
<id value="17" vendor="Khronos" tool="SPIR-V Tools Linker" comment="Contact David Neto, dneto@google.com"/>
<id value="18" vendor="Wine" tool="VKD3D Shader Compiler" comment="Contact wine-devel@winehq.org"/>
- <id value="19" vendor="Clay" tool="Clay Shader Compiler" comment="Contact info@clayengine.com"/>
+ <id value="19" vendor="Tellusim" tool="Clay Shader Compiler" comment="Contact info@tellusim.com"/>
<id value="20" vendor="W3C WebGPU Group" tool="WHLSL Shader Translator" comment="https://github.com/gpuweb/WHLSL"/>
<id value="21" vendor="Google" tool="Clspv" comment="Contact David Neto, dneto@google.com"/>
<id value="22" vendor="Google" tool="MLIR SPIR-V Serializer" comment="Contact Lei Zhang, antiagainst@google.com"/>
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h
new file mode 100644
index 00000000000..c52f32f8090
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h
@@ -0,0 +1,171 @@
+// Copyright (c) 2018 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_NonSemanticShaderDebugInfo100_H_
+#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ NonSemanticShaderDebugInfo100Version = 100,
+ NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff
+};
+enum {
+ NonSemanticShaderDebugInfo100Revision = 6,
+ NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100Instructions {
+ NonSemanticShaderDebugInfo100DebugInfoNone = 0,
+ NonSemanticShaderDebugInfo100DebugCompilationUnit = 1,
+ NonSemanticShaderDebugInfo100DebugTypeBasic = 2,
+ NonSemanticShaderDebugInfo100DebugTypePointer = 3,
+ NonSemanticShaderDebugInfo100DebugTypeQualifier = 4,
+ NonSemanticShaderDebugInfo100DebugTypeArray = 5,
+ NonSemanticShaderDebugInfo100DebugTypeVector = 6,
+ NonSemanticShaderDebugInfo100DebugTypedef = 7,
+ NonSemanticShaderDebugInfo100DebugTypeFunction = 8,
+ NonSemanticShaderDebugInfo100DebugTypeEnum = 9,
+ NonSemanticShaderDebugInfo100DebugTypeComposite = 10,
+ NonSemanticShaderDebugInfo100DebugTypeMember = 11,
+ NonSemanticShaderDebugInfo100DebugTypeInheritance = 12,
+ NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13,
+ NonSemanticShaderDebugInfo100DebugTypeTemplate = 14,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17,
+ NonSemanticShaderDebugInfo100DebugGlobalVariable = 18,
+ NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19,
+ NonSemanticShaderDebugInfo100DebugFunction = 20,
+ NonSemanticShaderDebugInfo100DebugLexicalBlock = 21,
+ NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22,
+ NonSemanticShaderDebugInfo100DebugScope = 23,
+ NonSemanticShaderDebugInfo100DebugNoScope = 24,
+ NonSemanticShaderDebugInfo100DebugInlinedAt = 25,
+ NonSemanticShaderDebugInfo100DebugLocalVariable = 26,
+ NonSemanticShaderDebugInfo100DebugInlinedVariable = 27,
+ NonSemanticShaderDebugInfo100DebugDeclare = 28,
+ NonSemanticShaderDebugInfo100DebugValue = 29,
+ NonSemanticShaderDebugInfo100DebugOperation = 30,
+ NonSemanticShaderDebugInfo100DebugExpression = 31,
+ NonSemanticShaderDebugInfo100DebugMacroDef = 32,
+ NonSemanticShaderDebugInfo100DebugMacroUndef = 33,
+ NonSemanticShaderDebugInfo100DebugImportedEntity = 34,
+ NonSemanticShaderDebugInfo100DebugSource = 35,
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101,
+ NonSemanticShaderDebugInfo100DebugSourceContinued = 102,
+ NonSemanticShaderDebugInfo100DebugLine = 103,
+ NonSemanticShaderDebugInfo100DebugNoLine = 104,
+ NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105,
+ NonSemanticShaderDebugInfo100DebugStoragePath = 106,
+ NonSemanticShaderDebugInfo100DebugEntryPoint = 107,
+ NonSemanticShaderDebugInfo100DebugTypeMatrix = 108,
+ NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff
+};
+
+
+enum NonSemanticShaderDebugInfo100DebugInfoFlags {
+ NonSemanticShaderDebugInfo100None = 0x0000,
+ NonSemanticShaderDebugInfo100FlagIsProtected = 0x01,
+ NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02,
+ NonSemanticShaderDebugInfo100FlagIsPublic = 0x03,
+ NonSemanticShaderDebugInfo100FlagIsLocal = 0x04,
+ NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08,
+ NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10,
+ NonSemanticShaderDebugInfo100FlagArtificial = 0x20,
+ NonSemanticShaderDebugInfo100FlagExplicit = 0x40,
+ NonSemanticShaderDebugInfo100FlagPrototyped = 0x80,
+ NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100,
+ NonSemanticShaderDebugInfo100FlagStaticMember = 0x200,
+ NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400,
+ NonSemanticShaderDebugInfo100FlagLValueReference = 0x800,
+ NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000,
+ NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000,
+ NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000,
+ NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000,
+ NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000,
+ NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000,
+ NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100BuildIdentifierFlags {
+ NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01,
+ NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding {
+ NonSemanticShaderDebugInfo100Unspecified = 0,
+ NonSemanticShaderDebugInfo100Address = 1,
+ NonSemanticShaderDebugInfo100Boolean = 2,
+ NonSemanticShaderDebugInfo100Float = 3,
+ NonSemanticShaderDebugInfo100Signed = 4,
+ NonSemanticShaderDebugInfo100SignedChar = 5,
+ NonSemanticShaderDebugInfo100Unsigned = 6,
+ NonSemanticShaderDebugInfo100UnsignedChar = 7,
+ NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugCompositeType {
+ NonSemanticShaderDebugInfo100Class = 0,
+ NonSemanticShaderDebugInfo100Structure = 1,
+ NonSemanticShaderDebugInfo100Union = 2,
+ NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugTypeQualifier {
+ NonSemanticShaderDebugInfo100ConstType = 0,
+ NonSemanticShaderDebugInfo100VolatileType = 1,
+ NonSemanticShaderDebugInfo100RestrictType = 2,
+ NonSemanticShaderDebugInfo100AtomicType = 3,
+ NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugOperation {
+ NonSemanticShaderDebugInfo100Deref = 0,
+ NonSemanticShaderDebugInfo100Plus = 1,
+ NonSemanticShaderDebugInfo100Minus = 2,
+ NonSemanticShaderDebugInfo100PlusUconst = 3,
+ NonSemanticShaderDebugInfo100BitPiece = 4,
+ NonSemanticShaderDebugInfo100Swap = 5,
+ NonSemanticShaderDebugInfo100Xderef = 6,
+ NonSemanticShaderDebugInfo100StackValue = 7,
+ NonSemanticShaderDebugInfo100Constu = 8,
+ NonSemanticShaderDebugInfo100Fragment = 9,
+ NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugImportedEntity {
+ NonSemanticShaderDebugInfo100ImportedModule = 0,
+ NonSemanticShaderDebugInfo100ImportedDeclaration = 1,
+ NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVulkanDebugInfo100.h b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVulkanDebugInfo100.h
deleted file mode 100644
index ede4b3d7740..00000000000
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVulkanDebugInfo100.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2018 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_NonSemanticVulkanDebugInfo100_H_
-#define SPIRV_UNIFIED1_NonSemanticVulkanDebugInfo100_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- NonSemanticVulkanDebugInfo100Version = 100,
- NonSemanticVulkanDebugInfo100Version_BitWidthPadding = 0x7fffffff
-};
-enum {
- NonSemanticVulkanDebugInfo100Revision = 6,
- NonSemanticVulkanDebugInfo100Revision_BitWidthPadding = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100Instructions {
- NonSemanticVulkanDebugInfo100DebugInfoNone = 0,
- NonSemanticVulkanDebugInfo100DebugCompilationUnit = 1,
- NonSemanticVulkanDebugInfo100DebugTypeBasic = 2,
- NonSemanticVulkanDebugInfo100DebugTypePointer = 3,
- NonSemanticVulkanDebugInfo100DebugTypeQualifier = 4,
- NonSemanticVulkanDebugInfo100DebugTypeArray = 5,
- NonSemanticVulkanDebugInfo100DebugTypeVector = 6,
- NonSemanticVulkanDebugInfo100DebugTypedef = 7,
- NonSemanticVulkanDebugInfo100DebugTypeFunction = 8,
- NonSemanticVulkanDebugInfo100DebugTypeEnum = 9,
- NonSemanticVulkanDebugInfo100DebugTypeComposite = 10,
- NonSemanticVulkanDebugInfo100DebugTypeMember = 11,
- NonSemanticVulkanDebugInfo100DebugTypeInheritance = 12,
- NonSemanticVulkanDebugInfo100DebugTypePtrToMember = 13,
- NonSemanticVulkanDebugInfo100DebugTypeTemplate = 14,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateParameter = 15,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateTemplateParameter = 16,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateParameterPack = 17,
- NonSemanticVulkanDebugInfo100DebugGlobalVariable = 18,
- NonSemanticVulkanDebugInfo100DebugFunctionDeclaration = 19,
- NonSemanticVulkanDebugInfo100DebugFunction = 20,
- NonSemanticVulkanDebugInfo100DebugLexicalBlock = 21,
- NonSemanticVulkanDebugInfo100DebugLexicalBlockDiscriminator = 22,
- NonSemanticVulkanDebugInfo100DebugScope = 23,
- NonSemanticVulkanDebugInfo100DebugNoScope = 24,
- NonSemanticVulkanDebugInfo100DebugInlinedAt = 25,
- NonSemanticVulkanDebugInfo100DebugLocalVariable = 26,
- NonSemanticVulkanDebugInfo100DebugInlinedVariable = 27,
- NonSemanticVulkanDebugInfo100DebugDeclare = 28,
- NonSemanticVulkanDebugInfo100DebugValue = 29,
- NonSemanticVulkanDebugInfo100DebugOperation = 30,
- NonSemanticVulkanDebugInfo100DebugExpression = 31,
- NonSemanticVulkanDebugInfo100DebugMacroDef = 32,
- NonSemanticVulkanDebugInfo100DebugMacroUndef = 33,
- NonSemanticVulkanDebugInfo100DebugImportedEntity = 34,
- NonSemanticVulkanDebugInfo100DebugSource = 35,
- NonSemanticVulkanDebugInfo100DebugFunctionDefinition = 101,
- NonSemanticVulkanDebugInfo100DebugSourceContinued = 102,
- NonSemanticVulkanDebugInfo100DebugLine = 103,
- NonSemanticVulkanDebugInfo100DebugNoLine = 104,
- NonSemanticVulkanDebugInfo100DebugBuildIdentifier = 105,
- NonSemanticVulkanDebugInfo100DebugStoragePath = 106,
- NonSemanticVulkanDebugInfo100DebugEntryPoint = 107,
- NonSemanticVulkanDebugInfo100DebugTypeMatrix = 108,
- NonSemanticVulkanDebugInfo100InstructionsMax = 0x7fffffff
-};
-
-
-enum NonSemanticVulkanDebugInfo100DebugInfoFlags {
- NonSemanticVulkanDebugInfo100None = 0x0000,
- NonSemanticVulkanDebugInfo100FlagIsProtected = 0x01,
- NonSemanticVulkanDebugInfo100FlagIsPrivate = 0x02,
- NonSemanticVulkanDebugInfo100FlagIsPublic = 0x03,
- NonSemanticVulkanDebugInfo100FlagIsLocal = 0x04,
- NonSemanticVulkanDebugInfo100FlagIsDefinition = 0x08,
- NonSemanticVulkanDebugInfo100FlagFwdDecl = 0x10,
- NonSemanticVulkanDebugInfo100FlagArtificial = 0x20,
- NonSemanticVulkanDebugInfo100FlagExplicit = 0x40,
- NonSemanticVulkanDebugInfo100FlagPrototyped = 0x80,
- NonSemanticVulkanDebugInfo100FlagObjectPointer = 0x100,
- NonSemanticVulkanDebugInfo100FlagStaticMember = 0x200,
- NonSemanticVulkanDebugInfo100FlagIndirectVariable = 0x400,
- NonSemanticVulkanDebugInfo100FlagLValueReference = 0x800,
- NonSemanticVulkanDebugInfo100FlagRValueReference = 0x1000,
- NonSemanticVulkanDebugInfo100FlagIsOptimized = 0x2000,
- NonSemanticVulkanDebugInfo100FlagIsEnumClass = 0x4000,
- NonSemanticVulkanDebugInfo100FlagTypePassByValue = 0x8000,
- NonSemanticVulkanDebugInfo100FlagTypePassByReference = 0x10000,
- NonSemanticVulkanDebugInfo100FlagUnknownPhysicalLayout = 0x20000,
- NonSemanticVulkanDebugInfo100DebugInfoFlagsMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100BuildIdentifierFlags {
- NonSemanticVulkanDebugInfo100IdentifierPossibleDuplicates = 0x01,
- NonSemanticVulkanDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugBaseTypeAttributeEncoding {
- NonSemanticVulkanDebugInfo100Unspecified = 0,
- NonSemanticVulkanDebugInfo100Address = 1,
- NonSemanticVulkanDebugInfo100Boolean = 2,
- NonSemanticVulkanDebugInfo100Float = 3,
- NonSemanticVulkanDebugInfo100Signed = 4,
- NonSemanticVulkanDebugInfo100SignedChar = 5,
- NonSemanticVulkanDebugInfo100Unsigned = 6,
- NonSemanticVulkanDebugInfo100UnsignedChar = 7,
- NonSemanticVulkanDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugCompositeType {
- NonSemanticVulkanDebugInfo100Class = 0,
- NonSemanticVulkanDebugInfo100Structure = 1,
- NonSemanticVulkanDebugInfo100Union = 2,
- NonSemanticVulkanDebugInfo100DebugCompositeTypeMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugTypeQualifier {
- NonSemanticVulkanDebugInfo100ConstType = 0,
- NonSemanticVulkanDebugInfo100VolatileType = 1,
- NonSemanticVulkanDebugInfo100RestrictType = 2,
- NonSemanticVulkanDebugInfo100AtomicType = 3,
- NonSemanticVulkanDebugInfo100DebugTypeQualifierMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugOperation {
- NonSemanticVulkanDebugInfo100Deref = 0,
- NonSemanticVulkanDebugInfo100Plus = 1,
- NonSemanticVulkanDebugInfo100Minus = 2,
- NonSemanticVulkanDebugInfo100PlusUconst = 3,
- NonSemanticVulkanDebugInfo100BitPiece = 4,
- NonSemanticVulkanDebugInfo100Swap = 5,
- NonSemanticVulkanDebugInfo100Xderef = 6,
- NonSemanticVulkanDebugInfo100StackValue = 7,
- NonSemanticVulkanDebugInfo100Constu = 8,
- NonSemanticVulkanDebugInfo100Fragment = 9,
- NonSemanticVulkanDebugInfo100DebugOperationMax = 0x7fffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugImportedEntity {
- NonSemanticVulkanDebugInfo100ImportedModule = 0,
- NonSemanticVulkanDebugInfo100ImportedDeclaration = 1,
- NonSemanticVulkanDebugInfo100DebugImportedEntityMax = 0x7fffffff
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // SPIRV_UNIFIED1_NonSemanticVulkanDebugInfo100_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json
index f3621b0b4f8..f3621b0b4f8 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json
index 2ff4f9a4427..9154496bac2 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json
@@ -4754,6 +4754,52 @@
"version" : "None"
},
{
+ "opname" : "OpTraceMotionNV",
+ "class" : "Reserved",
+ "opcode" : 5338,
+ "operands" : [
+
+ { "kind" : "IdRef", "name" : "'Accel'" },
+ { "kind" : "IdRef", "name" : "'Ray Flags'" },
+ { "kind" : "IdRef", "name" : "'Cull Mask'" },
+ { "kind" : "IdRef", "name" : "'SBT Offset'" },
+ { "kind" : "IdRef", "name" : "'SBT Stride'" },
+ { "kind" : "IdRef", "name" : "'Miss Index'" },
+ { "kind" : "IdRef", "name" : "'Ray Origin'" },
+ { "kind" : "IdRef", "name" : "'Ray Tmin'" },
+ { "kind" : "IdRef", "name" : "'Ray Direction'" },
+ { "kind" : "IdRef", "name" : "'Ray Tmax'" },
+ { "kind" : "IdRef", "name" : "'Time'" },
+ { "kind" : "IdRef", "name" : "'PayloadId'" }
+ ],
+ "capabilities" : [ "RayTracingMotionBlurNV" ],
+ "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ],
+ "version" : "None"
+ },
+ {
+ "opname" : "OpTraceRayMotionNV",
+ "class" : "Reserved",
+ "opcode" : 5339,
+ "operands" : [
+
+ { "kind" : "IdRef", "name" : "'Accel'" },
+ { "kind" : "IdRef", "name" : "'Ray Flags'" },
+ { "kind" : "IdRef", "name" : "'Cull Mask'" },
+ { "kind" : "IdRef", "name" : "'SBT Offset'" },
+ { "kind" : "IdRef", "name" : "'SBT Stride'" },
+ { "kind" : "IdRef", "name" : "'Miss Index'" },
+ { "kind" : "IdRef", "name" : "'Ray Origin'" },
+ { "kind" : "IdRef", "name" : "'Ray Tmin'" },
+ { "kind" : "IdRef", "name" : "'Ray Direction'" },
+ { "kind" : "IdRef", "name" : "'Ray Tmax'" },
+ { "kind" : "IdRef", "name" : "'Time'" },
+ { "kind" : "IdRef", "name" : "'Payload'" }
+ ],
+ "capabilities" : [ "RayTracingMotionBlurNV" ],
+ "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ],
+ "version" : "None"
+ },
+ {
"opname" : "OpTypeAccelerationStructureNV",
"class" : "Reserved",
"opcode" : 5341,
@@ -7631,24 +7677,6 @@
"version" : "None"
},
{
- "opname" : "OpArbitraryFloatPowNINTEL",
- "class" : "@exclude",
- "opcode" : 5882,
- "operands" : [
- { "kind" : "IdResultType" },
- { "kind" : "IdResult" },
- { "kind" : "IdRef", "name" : "'A'" },
- { "kind" : "LiteralInteger", "name" : "'M1'" },
- { "kind" : "IdRef", "name" : "'B'" },
- { "kind" : "LiteralInteger", "name" : "'Mout'" },
- { "kind" : "LiteralInteger", "name" : "'EnableSubnormals'" },
- { "kind" : "LiteralInteger", "name" : "'RoundingMode'" },
- { "kind" : "LiteralInteger", "name" : "'RoundingAccuracy'" }
- ],
- "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ],
- "version" : "None"
- },
- {
"opname" : "OpLoopControlINTEL",
"class" : "Reserved",
"opcode" : 5887,
@@ -8460,40 +8488,35 @@
},
{
"enumerant" : "NotNaN",
- "value" : "0x0001",
- "capabilities" : [ "Kernel" ]
+ "value" : "0x0001"
},
{
"enumerant" : "NotInf",
- "value" : "0x0002",
- "capabilities" : [ "Kernel" ]
+ "value" : "0x0002"
},
{
"enumerant" : "NSZ",
- "value" : "0x0004",
- "capabilities" : [ "Kernel" ]
+ "value" : "0x0004"
},
{
"enumerant" : "AllowRecip",
- "value" : "0x0008",
- "capabilities" : [ "Kernel" ]
+ "value" : "0x0008"
},
{
"enumerant" : "Fast",
- "value" : "0x0010",
- "capabilities" : [ "Kernel" ]
+ "value" : "0x0010"
},
{
"enumerant" : "AllowContractFastINTEL",
"value" : "0x10000",
"capabilities" : [ "FPFastMathModeINTEL" ],
- "version" : "None"
+ "version" : "None"
},
{
"enumerant" : "AllowReassocINTEL",
"value" : "0x20000",
"capabilities" : [ "FPFastMathModeINTEL" ],
- "version" : "None"
+ "version" : "None"
}
]
},
@@ -8692,7 +8715,9 @@
},
{
"enumerant" : "OptNoneINTEL",
- "value" : "0x10000"
+ "value" : "0x10000",
+ "capabilities" : [ "OptNoneINTEL" ],
+ "version" : "None"
}
]
},
@@ -12053,6 +12078,13 @@
"version" : "None"
},
{
+ "enumerant" : "CurrentRayTimeNV",
+ "value" : 5334,
+ "capabilities" : [ "RayTracingMotionBlurNV" ],
+ "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "IncomingRayFlagsNV",
"value" : 5351,
"capabilities" : [ "RayTracingNV" , "RayTracingKHR" ],
@@ -13085,6 +13117,13 @@
"version" : "None"
},
{
+ "enumerant" : "RayTracingMotionBlurNV",
+ "value" : 5341,
+ "capabilities" : [ "Shader" ],
+ "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ],
+ "version" : "None"
+ },
+ {
"enumerant" : "VulkanMemoryModel",
"value" : 5345,
"version" : "1.5"
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.cs b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.cs
index e03ff009143..b2ca3f0de89 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.cs
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.cs
@@ -651,6 +651,7 @@ namespace Spv
HitTNV = 5332,
HitKindKHR = 5333,
HitKindNV = 5333,
+ CurrentRayTimeNV = 5334,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -995,6 +996,7 @@ namespace Spv
StorageTexelBufferArrayNonUniformIndexing = 5312,
StorageTexelBufferArrayNonUniformIndexingEXT = 5312,
RayTracingNV = 5340,
+ RayTracingMotionBlurNV = 5341,
VulkanMemoryModel = 5345,
VulkanMemoryModelKHR = 5345,
VulkanMemoryModelDeviceScope = 5346,
@@ -1552,6 +1554,8 @@ namespace Spv
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h
index 79aa4f548c9..14439632356 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h
@@ -657,6 +657,7 @@ typedef enum SpvBuiltIn_ {
SpvBuiltInHitTNV = 5332,
SpvBuiltInHitKindKHR = 5333,
SpvBuiltInHitKindNV = 5333,
+ SpvBuiltInCurrentRayTimeNV = 5334,
SpvBuiltInIncomingRayFlagsKHR = 5351,
SpvBuiltInIncomingRayFlagsNV = 5351,
SpvBuiltInRayGeometryIndexKHR = 5352,
@@ -995,6 +996,7 @@ typedef enum SpvCapability_ {
SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
SpvCapabilityRayTracingNV = 5340,
+ SpvCapabilityRayTracingMotionBlurNV = 5341,
SpvCapabilityVulkanMemoryModel = 5345,
SpvCapabilityVulkanMemoryModelKHR = 5345,
SpvCapabilityVulkanMemoryModelDeviceScope = 5346,
@@ -1550,6 +1552,8 @@ typedef enum SpvOp_ {
SpvOpIgnoreIntersectionNV = 5335,
SpvOpTerminateRayNV = 5336,
SpvOpTraceNV = 5337,
+ SpvOpTraceMotionNV = 5338,
+ SpvOpTraceRayMotionNV = 5339,
SpvOpTypeAccelerationStructureKHR = 5341,
SpvOpTypeAccelerationStructureNV = 5341,
SpvOpExecuteCallableNV = 5344,
@@ -2195,6 +2199,8 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy
case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+ case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp
index 2e31ef1db1a..5180457ce0a 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp
@@ -653,6 +653,7 @@ enum BuiltIn {
BuiltInHitTNV = 5332,
BuiltInHitKindKHR = 5333,
BuiltInHitKindNV = 5333,
+ BuiltInCurrentRayTimeNV = 5334,
BuiltInIncomingRayFlagsKHR = 5351,
BuiltInIncomingRayFlagsNV = 5351,
BuiltInRayGeometryIndexKHR = 5352,
@@ -991,6 +992,7 @@ enum Capability {
CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312,
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
CapabilityRayTracingNV = 5340,
+ CapabilityRayTracingMotionBlurNV = 5341,
CapabilityVulkanMemoryModel = 5345,
CapabilityVulkanMemoryModelKHR = 5345,
CapabilityVulkanMemoryModelDeviceScope = 5346,
@@ -1546,6 +1548,8 @@ enum Op {
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
@@ -2191,6 +2195,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case OpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+ case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11 b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11
index d0231346208..51e902498a0 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11
@@ -653,6 +653,7 @@ enum class BuiltIn : unsigned {
HitTNV = 5332,
HitKindKHR = 5333,
HitKindNV = 5333,
+ CurrentRayTimeNV = 5334,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -991,6 +992,7 @@ enum class Capability : unsigned {
StorageTexelBufferArrayNonUniformIndexing = 5312,
StorageTexelBufferArrayNonUniformIndexingEXT = 5312,
RayTracingNV = 5340,
+ RayTracingMotionBlurNV = 5341,
VulkanMemoryModel = 5345,
VulkanMemoryModelKHR = 5345,
VulkanMemoryModelDeviceScope = 5346,
@@ -1546,6 +1548,8 @@ enum class Op : unsigned {
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
@@ -2191,6 +2195,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case Op::OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break;
case Op::OpTerminateRayNV: *hasResult = false; *hasResultType = false; break;
case Op::OpTraceNV: *hasResult = false; *hasResultType = false; break;
+ case Op::OpTraceMotionNV: *hasResult = false; *hasResultType = false; break;
+ case Op::OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break;
case Op::OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break;
case Op::OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break;
case Op::OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json
index e3549283912..017b842b0ac 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json
@@ -684,6 +684,7 @@
"HitTNV": 5332,
"HitKindKHR": 5333,
"HitKindNV": 5333,
+ "CurrentRayTimeNV": 5334,
"IncomingRayFlagsKHR": 5351,
"IncomingRayFlagsNV": 5351,
"RayGeometryIndexKHR": 5352,
@@ -977,6 +978,7 @@
"StorageTexelBufferArrayNonUniformIndexing": 5312,
"StorageTexelBufferArrayNonUniformIndexingEXT": 5312,
"RayTracingNV": 5340,
+ "RayTracingMotionBlurNV": 5341,
"VulkanMemoryModel": 5345,
"VulkanMemoryModelKHR": 5345,
"VulkanMemoryModelDeviceScope": 5346,
@@ -1543,6 +1545,8 @@
"OpIgnoreIntersectionNV": 5335,
"OpTerminateRayNV": 5336,
"OpTraceNV": 5337,
+ "OpTraceMotionNV": 5338,
+ "OpTraceRayMotionNV": 5339,
"OpTypeAccelerationStructureKHR": 5341,
"OpTypeAccelerationStructureNV": 5341,
"OpExecuteCallableNV": 5344,
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.lua b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.lua
index 2ecffbd4087..46665d82183 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.lua
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.lua
@@ -625,6 +625,7 @@ spv = {
HitTNV = 5332,
HitKindKHR = 5333,
HitKindNV = 5333,
+ CurrentRayTimeNV = 5334,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -953,6 +954,7 @@ spv = {
StorageTexelBufferArrayNonUniformIndexing = 5312,
StorageTexelBufferArrayNonUniformIndexingEXT = 5312,
RayTracingNV = 5340,
+ RayTracingMotionBlurNV = 5341,
VulkanMemoryModel = 5345,
VulkanMemoryModelKHR = 5345,
VulkanMemoryModelDeviceScope = 5346,
@@ -1497,6 +1499,8 @@ spv = {
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.py b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.py
index d9be8014aaf..a7801919c71 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.py
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.py
@@ -625,6 +625,7 @@ spv = {
'HitTNV' : 5332,
'HitKindKHR' : 5333,
'HitKindNV' : 5333,
+ 'CurrentRayTimeNV' : 5334,
'IncomingRayFlagsKHR' : 5351,
'IncomingRayFlagsNV' : 5351,
'RayGeometryIndexKHR' : 5352,
@@ -953,6 +954,7 @@ spv = {
'StorageTexelBufferArrayNonUniformIndexing' : 5312,
'StorageTexelBufferArrayNonUniformIndexingEXT' : 5312,
'RayTracingNV' : 5340,
+ 'RayTracingMotionBlurNV' : 5341,
'VulkanMemoryModel' : 5345,
'VulkanMemoryModelKHR' : 5345,
'VulkanMemoryModelDeviceScope' : 5346,
@@ -1497,6 +1499,8 @@ spv = {
'OpIgnoreIntersectionNV' : 5335,
'OpTerminateRayNV' : 5336,
'OpTraceNV' : 5337,
+ 'OpTraceMotionNV' : 5338,
+ 'OpTraceRayMotionNV' : 5339,
'OpTypeAccelerationStructureKHR' : 5341,
'OpTypeAccelerationStructureNV' : 5341,
'OpExecuteCallableNV' : 5344,
diff --git a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spv.d b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spv.d
index cb7927d1a50..b85517a2f9c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spv.d
+++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spv.d
@@ -654,6 +654,7 @@ enum BuiltIn : uint
HitTNV = 5332,
HitKindKHR = 5333,
HitKindNV = 5333,
+ CurrentRayTimeNV = 5334,
IncomingRayFlagsKHR = 5351,
IncomingRayFlagsNV = 5351,
RayGeometryIndexKHR = 5352,
@@ -998,6 +999,7 @@ enum Capability : uint
StorageTexelBufferArrayNonUniformIndexing = 5312,
StorageTexelBufferArrayNonUniformIndexingEXT = 5312,
RayTracingNV = 5340,
+ RayTracingMotionBlurNV = 5341,
VulkanMemoryModel = 5345,
VulkanMemoryModelKHR = 5345,
VulkanMemoryModelDeviceScope = 5346,
@@ -1555,6 +1557,8 @@ enum Op : uint
OpIgnoreIntersectionNV = 5335,
OpTerminateRayNV = 5336,
OpTraceNV = 5337,
+ OpTraceMotionNV = 5338,
+ OpTraceRayMotionNV = 5339,
OpTypeAccelerationStructureKHR = 5341,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticShaderDebugInfo100.h b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticShaderDebugInfo100.h
new file mode 100644
index 00000000000..9db6951a84e
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticShaderDebugInfo100.h
@@ -0,0 +1,165 @@
+// Copyright (c) 2018 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_EXTINST_NonSemanticShaderDebugInfo100_H_
+#define SPIRV_EXTINST_NonSemanticShaderDebugInfo100_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum { NonSemanticShaderDebugInfo100Version = 100, NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff };
+enum { NonSemanticShaderDebugInfo100Revision = 6, NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff };
+
+enum NonSemanticShaderDebugInfo100Instructions {
+ NonSemanticShaderDebugInfo100DebugInfoNone = 0,
+ NonSemanticShaderDebugInfo100DebugCompilationUnit = 1,
+ NonSemanticShaderDebugInfo100DebugTypeBasic = 2,
+ NonSemanticShaderDebugInfo100DebugTypePointer = 3,
+ NonSemanticShaderDebugInfo100DebugTypeQualifier = 4,
+ NonSemanticShaderDebugInfo100DebugTypeArray = 5,
+ NonSemanticShaderDebugInfo100DebugTypeVector = 6,
+ NonSemanticShaderDebugInfo100DebugTypedef = 7,
+ NonSemanticShaderDebugInfo100DebugTypeFunction = 8,
+ NonSemanticShaderDebugInfo100DebugTypeEnum = 9,
+ NonSemanticShaderDebugInfo100DebugTypeComposite = 10,
+ NonSemanticShaderDebugInfo100DebugTypeMember = 11,
+ NonSemanticShaderDebugInfo100DebugTypeInheritance = 12,
+ NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13,
+ NonSemanticShaderDebugInfo100DebugTypeTemplate = 14,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16,
+ NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17,
+ NonSemanticShaderDebugInfo100DebugGlobalVariable = 18,
+ NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19,
+ NonSemanticShaderDebugInfo100DebugFunction = 20,
+ NonSemanticShaderDebugInfo100DebugLexicalBlock = 21,
+ NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22,
+ NonSemanticShaderDebugInfo100DebugScope = 23,
+ NonSemanticShaderDebugInfo100DebugNoScope = 24,
+ NonSemanticShaderDebugInfo100DebugInlinedAt = 25,
+ NonSemanticShaderDebugInfo100DebugLocalVariable = 26,
+ NonSemanticShaderDebugInfo100DebugInlinedVariable = 27,
+ NonSemanticShaderDebugInfo100DebugDeclare = 28,
+ NonSemanticShaderDebugInfo100DebugValue = 29,
+ NonSemanticShaderDebugInfo100DebugOperation = 30,
+ NonSemanticShaderDebugInfo100DebugExpression = 31,
+ NonSemanticShaderDebugInfo100DebugMacroDef = 32,
+ NonSemanticShaderDebugInfo100DebugMacroUndef = 33,
+ NonSemanticShaderDebugInfo100DebugImportedEntity = 34,
+ NonSemanticShaderDebugInfo100DebugSource = 35,
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101,
+ NonSemanticShaderDebugInfo100DebugSourceContinued = 102,
+ NonSemanticShaderDebugInfo100DebugLine = 103,
+ NonSemanticShaderDebugInfo100DebugNoLine = 104,
+ NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105,
+ NonSemanticShaderDebugInfo100DebugStoragePath = 106,
+ NonSemanticShaderDebugInfo100DebugEntryPoint = 107,
+ NonSemanticShaderDebugInfo100DebugTypeMatrix = 108,
+ NonSemanticShaderDebugInfo100InstructionsMax = 0x7ffffff
+};
+
+
+enum NonSemanticShaderDebugInfo100DebugInfoFlags {
+ NonSemanticShaderDebugInfo100None = 0x0000,
+ NonSemanticShaderDebugInfo100FlagIsProtected = 0x01,
+ NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02,
+ NonSemanticShaderDebugInfo100FlagIsPublic = 0x03,
+ NonSemanticShaderDebugInfo100FlagIsLocal = 0x04,
+ NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08,
+ NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10,
+ NonSemanticShaderDebugInfo100FlagArtificial = 0x20,
+ NonSemanticShaderDebugInfo100FlagExplicit = 0x40,
+ NonSemanticShaderDebugInfo100FlagPrototyped = 0x80,
+ NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100,
+ NonSemanticShaderDebugInfo100FlagStaticMember = 0x200,
+ NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400,
+ NonSemanticShaderDebugInfo100FlagLValueReference = 0x800,
+ NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000,
+ NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000,
+ NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000,
+ NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000,
+ NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000,
+ NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000,
+ NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100BuildIdentifierFlags {
+ NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01,
+ NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding {
+ NonSemanticShaderDebugInfo100Unspecified = 0,
+ NonSemanticShaderDebugInfo100Address = 1,
+ NonSemanticShaderDebugInfo100Boolean = 2,
+ NonSemanticShaderDebugInfo100Float = 3,
+ NonSemanticShaderDebugInfo100Signed = 4,
+ NonSemanticShaderDebugInfo100SignedChar = 5,
+ NonSemanticShaderDebugInfo100Unsigned = 6,
+ NonSemanticShaderDebugInfo100UnsignedChar = 7,
+ NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugCompositeType {
+ NonSemanticShaderDebugInfo100Class = 0,
+ NonSemanticShaderDebugInfo100Structure = 1,
+ NonSemanticShaderDebugInfo100Union = 2,
+ NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugTypeQualifier {
+ NonSemanticShaderDebugInfo100ConstType = 0,
+ NonSemanticShaderDebugInfo100VolatileType = 1,
+ NonSemanticShaderDebugInfo100RestrictType = 2,
+ NonSemanticShaderDebugInfo100AtomicType = 3,
+ NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugOperation {
+ NonSemanticShaderDebugInfo100Deref = 0,
+ NonSemanticShaderDebugInfo100Plus = 1,
+ NonSemanticShaderDebugInfo100Minus = 2,
+ NonSemanticShaderDebugInfo100PlusUconst = 3,
+ NonSemanticShaderDebugInfo100BitPiece = 4,
+ NonSemanticShaderDebugInfo100Swap = 5,
+ NonSemanticShaderDebugInfo100Xderef = 6,
+ NonSemanticShaderDebugInfo100StackValue = 7,
+ NonSemanticShaderDebugInfo100Constu = 8,
+ NonSemanticShaderDebugInfo100Fragment = 9,
+ NonSemanticShaderDebugInfo100DebugOperationMax = 0x7ffffff
+};
+
+enum NonSemanticShaderDebugInfo100DebugImportedEntity {
+ NonSemanticShaderDebugInfo100ImportedModule = 0,
+ NonSemanticShaderDebugInfo100ImportedDeclaration = 1,
+ NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7ffffff
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SPIRV_EXTINST_NonSemanticShaderDebugInfo100_H_ \ No newline at end of file
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticVulkanDebugInfo100.h b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticVulkanDebugInfo100.h
deleted file mode 100644
index 26af4bbb24e..00000000000
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticVulkanDebugInfo100.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2018 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_EXTINST_NonSemanticVulkanDebugInfo100_H_
-#define SPIRV_EXTINST_NonSemanticVulkanDebugInfo100_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum { NonSemanticVulkanDebugInfo100Version = 100, NonSemanticVulkanDebugInfo100Version_BitWidthPadding = 0x7fffffff };
-enum { NonSemanticVulkanDebugInfo100Revision = 6, NonSemanticVulkanDebugInfo100Revision_BitWidthPadding = 0x7fffffff };
-
-enum NonSemanticVulkanDebugInfo100Instructions {
- NonSemanticVulkanDebugInfo100DebugInfoNone = 0,
- NonSemanticVulkanDebugInfo100DebugCompilationUnit = 1,
- NonSemanticVulkanDebugInfo100DebugTypeBasic = 2,
- NonSemanticVulkanDebugInfo100DebugTypePointer = 3,
- NonSemanticVulkanDebugInfo100DebugTypeQualifier = 4,
- NonSemanticVulkanDebugInfo100DebugTypeArray = 5,
- NonSemanticVulkanDebugInfo100DebugTypeVector = 6,
- NonSemanticVulkanDebugInfo100DebugTypedef = 7,
- NonSemanticVulkanDebugInfo100DebugTypeFunction = 8,
- NonSemanticVulkanDebugInfo100DebugTypeEnum = 9,
- NonSemanticVulkanDebugInfo100DebugTypeComposite = 10,
- NonSemanticVulkanDebugInfo100DebugTypeMember = 11,
- NonSemanticVulkanDebugInfo100DebugTypeInheritance = 12,
- NonSemanticVulkanDebugInfo100DebugTypePtrToMember = 13,
- NonSemanticVulkanDebugInfo100DebugTypeTemplate = 14,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateParameter = 15,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateTemplateParameter = 16,
- NonSemanticVulkanDebugInfo100DebugTypeTemplateParameterPack = 17,
- NonSemanticVulkanDebugInfo100DebugGlobalVariable = 18,
- NonSemanticVulkanDebugInfo100DebugFunctionDeclaration = 19,
- NonSemanticVulkanDebugInfo100DebugFunction = 20,
- NonSemanticVulkanDebugInfo100DebugLexicalBlock = 21,
- NonSemanticVulkanDebugInfo100DebugLexicalBlockDiscriminator = 22,
- NonSemanticVulkanDebugInfo100DebugScope = 23,
- NonSemanticVulkanDebugInfo100DebugNoScope = 24,
- NonSemanticVulkanDebugInfo100DebugInlinedAt = 25,
- NonSemanticVulkanDebugInfo100DebugLocalVariable = 26,
- NonSemanticVulkanDebugInfo100DebugInlinedVariable = 27,
- NonSemanticVulkanDebugInfo100DebugDeclare = 28,
- NonSemanticVulkanDebugInfo100DebugValue = 29,
- NonSemanticVulkanDebugInfo100DebugOperation = 30,
- NonSemanticVulkanDebugInfo100DebugExpression = 31,
- NonSemanticVulkanDebugInfo100DebugMacroDef = 32,
- NonSemanticVulkanDebugInfo100DebugMacroUndef = 33,
- NonSemanticVulkanDebugInfo100DebugImportedEntity = 34,
- NonSemanticVulkanDebugInfo100DebugSource = 35,
- NonSemanticVulkanDebugInfo100DebugFunctionDefinition = 101,
- NonSemanticVulkanDebugInfo100DebugSourceContinued = 102,
- NonSemanticVulkanDebugInfo100DebugLine = 103,
- NonSemanticVulkanDebugInfo100DebugNoLine = 104,
- NonSemanticVulkanDebugInfo100DebugBuildIdentifier = 105,
- NonSemanticVulkanDebugInfo100DebugStoragePath = 106,
- NonSemanticVulkanDebugInfo100DebugEntryPoint = 107,
- NonSemanticVulkanDebugInfo100DebugTypeMatrix = 108,
- NonSemanticVulkanDebugInfo100InstructionsMax = 0x7ffffff
-};
-
-
-enum NonSemanticVulkanDebugInfo100DebugInfoFlags {
- NonSemanticVulkanDebugInfo100None = 0x0000,
- NonSemanticVulkanDebugInfo100FlagIsProtected = 0x01,
- NonSemanticVulkanDebugInfo100FlagIsPrivate = 0x02,
- NonSemanticVulkanDebugInfo100FlagIsPublic = 0x03,
- NonSemanticVulkanDebugInfo100FlagIsLocal = 0x04,
- NonSemanticVulkanDebugInfo100FlagIsDefinition = 0x08,
- NonSemanticVulkanDebugInfo100FlagFwdDecl = 0x10,
- NonSemanticVulkanDebugInfo100FlagArtificial = 0x20,
- NonSemanticVulkanDebugInfo100FlagExplicit = 0x40,
- NonSemanticVulkanDebugInfo100FlagPrototyped = 0x80,
- NonSemanticVulkanDebugInfo100FlagObjectPointer = 0x100,
- NonSemanticVulkanDebugInfo100FlagStaticMember = 0x200,
- NonSemanticVulkanDebugInfo100FlagIndirectVariable = 0x400,
- NonSemanticVulkanDebugInfo100FlagLValueReference = 0x800,
- NonSemanticVulkanDebugInfo100FlagRValueReference = 0x1000,
- NonSemanticVulkanDebugInfo100FlagIsOptimized = 0x2000,
- NonSemanticVulkanDebugInfo100FlagIsEnumClass = 0x4000,
- NonSemanticVulkanDebugInfo100FlagTypePassByValue = 0x8000,
- NonSemanticVulkanDebugInfo100FlagTypePassByReference = 0x10000,
- NonSemanticVulkanDebugInfo100FlagUnknownPhysicalLayout = 0x20000,
- NonSemanticVulkanDebugInfo100DebugInfoFlagsMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100BuildIdentifierFlags {
- NonSemanticVulkanDebugInfo100IdentifierPossibleDuplicates = 0x01,
- NonSemanticVulkanDebugInfo100BuildIdentifierFlagsMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugBaseTypeAttributeEncoding {
- NonSemanticVulkanDebugInfo100Unspecified = 0,
- NonSemanticVulkanDebugInfo100Address = 1,
- NonSemanticVulkanDebugInfo100Boolean = 2,
- NonSemanticVulkanDebugInfo100Float = 3,
- NonSemanticVulkanDebugInfo100Signed = 4,
- NonSemanticVulkanDebugInfo100SignedChar = 5,
- NonSemanticVulkanDebugInfo100Unsigned = 6,
- NonSemanticVulkanDebugInfo100UnsignedChar = 7,
- NonSemanticVulkanDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugCompositeType {
- NonSemanticVulkanDebugInfo100Class = 0,
- NonSemanticVulkanDebugInfo100Structure = 1,
- NonSemanticVulkanDebugInfo100Union = 2,
- NonSemanticVulkanDebugInfo100DebugCompositeTypeMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugTypeQualifier {
- NonSemanticVulkanDebugInfo100ConstType = 0,
- NonSemanticVulkanDebugInfo100VolatileType = 1,
- NonSemanticVulkanDebugInfo100RestrictType = 2,
- NonSemanticVulkanDebugInfo100AtomicType = 3,
- NonSemanticVulkanDebugInfo100DebugTypeQualifierMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugOperation {
- NonSemanticVulkanDebugInfo100Deref = 0,
- NonSemanticVulkanDebugInfo100Plus = 1,
- NonSemanticVulkanDebugInfo100Minus = 2,
- NonSemanticVulkanDebugInfo100PlusUconst = 3,
- NonSemanticVulkanDebugInfo100BitPiece = 4,
- NonSemanticVulkanDebugInfo100Swap = 5,
- NonSemanticVulkanDebugInfo100Xderef = 6,
- NonSemanticVulkanDebugInfo100StackValue = 7,
- NonSemanticVulkanDebugInfo100Constu = 8,
- NonSemanticVulkanDebugInfo100Fragment = 9,
- NonSemanticVulkanDebugInfo100DebugOperationMax = 0x7ffffff
-};
-
-enum NonSemanticVulkanDebugInfo100DebugImportedEntity {
- NonSemanticVulkanDebugInfo100ImportedModule = 0,
- NonSemanticVulkanDebugInfo100ImportedDeclaration = 1,
- NonSemanticVulkanDebugInfo100DebugImportedEntityMax = 0x7ffffff
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // SPIRV_EXTINST_NonSemanticVulkanDebugInfo100_H_ \ No newline at end of file
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc
index 7252aa2744f..59e49342d67 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc
@@ -1 +1 @@
-"v2021.3-dev", "SPIRV-Tools v2021.3-dev 25ef0e5c8566c2abe88852e3b72e0facccbbbcb9"
+"v2021.4-dev", "SPIRV-Tools v2021.4-dev 133b7ce91f51ffb26e674a856ec6692cca650ab3"
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
index 77fdff6ec6e..88c578b201c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc
@@ -44,6 +44,7 @@ static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
static const SpvCapability pygen_variable_caps_RayQueryKHR[] = {SpvCapabilityRayQueryKHR};
static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityRayTracingKHR};
static const SpvCapability pygen_variable_caps_RayTracingKHRRayQueryKHR[] = {SpvCapabilityRayTracingKHR, SpvCapabilityRayQueryKHR};
+static const SpvCapability pygen_variable_caps_RayTracingMotionBlurNV[] = {SpvCapabilityRayTracingMotionBlurNV};
static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR, SpvCapabilityRayQueryKHR};
@@ -90,6 +91,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spv
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_NV_ray_tracing, spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query};
+static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing_motion_blur[] = {spvtools::Extension::kSPV_NV_ray_tracing_motion_blur};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_subgroup_partitioned[] = {spvtools::Extension::kSPV_NV_shader_subgroup_partitioned};
@@ -482,6 +484,8 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"IgnoreIntersectionNV", SpvOpIgnoreIntersectionNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TerminateRayNV", SpvOpTerminateRayNV, 1, pygen_variable_caps_RayTracingNV, 0, {}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
{"TraceNV", SpvOpTraceNV, 1, pygen_variable_caps_RayTracingNV, 11, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
+ {"TraceMotionNV", SpvOpTraceMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu},
+ {"TraceRayMotionNV", SpvOpTraceRayMotionNV, 1, pygen_variable_caps_RayTracingMotionBlurNV, 12, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureKHR", SpvOpTypeAccelerationStructureKHR, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"TypeAccelerationStructureNV", SpvOpTypeAccelerationStructureNV, 3, pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 3, pygen_variable_exts_SPV_NV_ray_tracingSPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu},
{"ExecuteCallableNV", SpvOpExecuteCallableNV, 1, pygen_variable_caps_RayTracingNV, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_NV_ray_tracing, 0xffffffffu, 0xffffffffu},
@@ -693,7 +697,6 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = {
{"ArbitraryFloatPowINTEL", SpvOpArbitraryFloatPowINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ArbitraryFloatPowRINTEL", SpvOpArbitraryFloatPowRINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 10, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"ArbitraryFloatPowNINTEL", SpvOpArbitraryFloatPowNINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
- {"ArbitraryFloatPowNINTEL", SpvOpArbitraryFloatPowNINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFloatingPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"LoopControlINTEL", SpvOpLoopControlINTEL, 1, pygen_variable_caps_UnstructuredLoopControlsINTEL, 1, {SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER}, 0, 0, 1, pygen_variable_exts_SPV_INTEL_unstructured_loop_controls, 0xffffffffu, 0xffffffffu},
{"FixedSqrtINTEL", SpvOpFixedSqrtINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
{"FixedRecipINTEL", SpvOpFixedRecipINTEL, 1, pygen_variable_caps_ArbitraryPrecisionFixedPointINTEL, 9, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu},
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
index ec3226f80d0..9b7aba927cb 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc
@@ -174,6 +174,8 @@ const char* ExtensionToString(Extension extension) {
return "SPV_NV_mesh_shader";
case Extension::kSPV_NV_ray_tracing:
return "SPV_NV_ray_tracing";
+ case Extension::kSPV_NV_ray_tracing_motion_blur:
+ return "SPV_NV_ray_tracing_motion_blur";
case Extension::kSPV_NV_sample_mask_override_coverage:
return "SPV_NV_sample_mask_override_coverage";
case Extension::kSPV_NV_shader_image_footprint:
@@ -197,8 +199,8 @@ const char* ExtensionToString(Extension extension) {
bool GetExtensionFromString(const char* str, Extension* extension) {
- static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_optnone", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
- static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
+ static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_optnone", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
+ static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
const auto b = std::begin(known_ext_strs);
const auto e = std::end(known_ext_strs);
const auto found = std::equal_range(
@@ -476,6 +478,8 @@ const char* CapabilityToString(SpvCapability capability) {
return "StorageTexelBufferArrayNonUniformIndexing";
case SpvCapabilityRayTracingNV:
return "RayTracingNV";
+ case SpvCapabilityRayTracingMotionBlurNV:
+ return "RayTracingMotionBlurNV";
case SpvCapabilityVulkanMemoryModel:
return "VulkanMemoryModel";
case SpvCapabilityVulkanMemoryModelDeviceScope:
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc
index 399471bf28a..8499ab6fabb 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc
@@ -85,6 +85,7 @@ kSPV_NV_fragment_shader_barycentric,
kSPV_NV_geometry_shader_passthrough,
kSPV_NV_mesh_shader,
kSPV_NV_ray_tracing,
+kSPV_NV_ray_tracing_motion_blur,
kSPV_NV_sample_mask_override_coverage,
kSPV_NV_shader_image_footprint,
kSPV_NV_shader_sm_builtins,
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/generators.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/generators.inc
index 43ed6e9ab09..91fc0922ea6 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/generators.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/generators.inc
@@ -17,7 +17,7 @@
{16, "X-LEGEND", "Mesa-IR/SPIR-V Translator", "X-LEGEND Mesa-IR/SPIR-V Translator"},
{17, "Khronos", "SPIR-V Tools Linker", "Khronos SPIR-V Tools Linker"},
{18, "Wine", "VKD3D Shader Compiler", "Wine VKD3D Shader Compiler"},
-{19, "Clay", "Clay Shader Compiler", "Clay Clay Shader Compiler"},
+{19, "Tellusim", "Clay Shader Compiler", "Tellusim Clay Shader Compiler"},
{20, "W3C WebGPU Group", "WHLSL Shader Translator", "W3C WebGPU Group WHLSL Shader Translator"},
{21, "Google", "Clspv", "Google Clspv"},
{22, "Google", "MLIR SPIR-V Serializer", "Google MLIR SPIR-V Serializer"},
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vulkan.debuginfo.100.insts.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc
index dff31513538..27ce78fa94f 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vulkan.debuginfo.100.insts.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc
@@ -1,6 +1,6 @@
-static const spv_ext_inst_desc_t nonsemantic_vulkan_debuginfo_100_entries[] = {
+static const spv_ext_inst_desc_t nonsemantic_shader_debuginfo_100_entries[] = {
{"DebugInfoNone", 0, 0, nullptr, {SPV_OPERAND_TYPE_NONE}},
{"DebugCompilationUnit", 1, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
{"DebugTypeBasic", 2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}},
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
index fc09e2d81a1..408e379c2ad 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc
@@ -64,12 +64,14 @@ static const SpvCapability pygen_variable_caps_MinLod[] = {SpvCapabilityMinLod};
static const SpvCapability pygen_variable_caps_MultiView[] = {SpvCapabilityMultiView};
static const SpvCapability pygen_variable_caps_MultiViewport[] = {SpvCapabilityMultiViewport};
static const SpvCapability pygen_variable_caps_MultiViewportShaderViewportIndexShaderViewportIndexLayerEXTMeshShadingNV[] = {SpvCapabilityMultiViewport, SpvCapabilityShaderViewportIndex, SpvCapabilityShaderViewportIndexLayerEXT, SpvCapabilityMeshShadingNV};
+static const SpvCapability pygen_variable_caps_OptNoneINTEL[] = {SpvCapabilityOptNoneINTEL};
static const SpvCapability pygen_variable_caps_PerViewAttributesNVMeshShadingNV[] = {SpvCapabilityPerViewAttributesNV, SpvCapabilityMeshShadingNV};
static const SpvCapability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {SpvCapabilityPhysicalStorageBufferAddresses};
static const SpvCapability pygen_variable_caps_Pipes[] = {SpvCapabilityPipes};
static const SpvCapability pygen_variable_caps_RayQueryKHR[] = {SpvCapabilityRayQueryKHR};
static const SpvCapability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {SpvCapabilityRayQueryKHR, SpvCapabilityRayTracingKHR};
static const SpvCapability pygen_variable_caps_RayTracingKHR[] = {SpvCapabilityRayTracingKHR};
+static const SpvCapability pygen_variable_caps_RayTracingMotionBlurNV[] = {SpvCapabilityRayTracingMotionBlurNV};
static const SpvCapability pygen_variable_caps_RayTracingNV[] = {SpvCapabilityRayTracingNV};
static const SpvCapability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {SpvCapabilityRayTracingNV, SpvCapabilityRayTracingKHR};
static const SpvCapability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {SpvCapabilityRayTraversalPrimitiveCullingKHR};
@@ -199,6 +201,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_pass
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_NV_mesh_shader};
static const spvtools::Extension pygen_variable_exts_SPV_NV_mesh_shaderSPV_NV_viewport_array2[] = {spvtools::Extension::kSPV_NV_mesh_shader, spvtools::Extension::kSPV_NV_viewport_array2};
static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing[] = {spvtools::Extension::kSPV_NV_ray_tracing};
+static const spvtools::Extension pygen_variable_exts_SPV_NV_ray_tracing_motion_blur[] = {spvtools::Extension::kSPV_NV_ray_tracing_motion_blur};
static const spvtools::Extension pygen_variable_exts_SPV_NV_sample_mask_override_coverage[] = {spvtools::Extension::kSPV_NV_sample_mask_override_coverage};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_image_footprint[] = {spvtools::Extension::kSPV_NV_shader_image_footprint};
static const spvtools::Extension pygen_variable_exts_SPV_NV_shader_sm_builtins[] = {spvtools::Extension::kSPV_NV_shader_sm_builtins};
@@ -230,11 +233,11 @@ static const spv_operand_desc_t pygen_variable_ImageOperandsEntries[] = {
static const spv_operand_desc_t pygen_variable_FPFastMathModeEntries[] = {
{"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"NotNaN", 0x0001, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"NotInf", 0x0002, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"NSZ", 0x0004, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"AllowRecip", 0x0008, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"Fast", 0x0010, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+ {"NotNaN", 0x0001, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+ {"NotInf", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+ {"NSZ", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+ {"AllowRecip", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
+ {"Fast", 0x0010, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"AllowContractFastINTEL", 0x10000, 1, pygen_variable_caps_FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu},
{"AllowReassocINTEL", 0x20000, 1, pygen_variable_caps_FPFastMathModeINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
@@ -272,7 +275,7 @@ static const spv_operand_desc_t pygen_variable_FunctionControlEntries[] = {
{"DontInline", 0x0002, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Pure", 0x0004, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
{"Const", 0x0008, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu},
- {"OptNoneINTEL", 0x10000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}
+ {"OptNoneINTEL", 0x10000, 1, pygen_variable_caps_OptNoneINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}
};
static const spv_operand_desc_t pygen_variable_MemorySemanticsEntries[] = {
@@ -876,6 +879,7 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = {
{"HitTNV", 5332, 1, pygen_variable_caps_RayTracingNV, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"HitKindNV", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"HitKindKHR", 5333, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
+ {"CurrentRayTimeNV", 5334, 1, pygen_variable_caps_RayTracingMotionBlurNV, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayFlagsNV", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"IncomingRayFlagsKHR", 5351, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
{"RayGeometryIndexKHR", 5352, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_KHR_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
@@ -1060,6 +1064,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = {
{"StorageTexelBufferArrayNonUniformIndexing", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"StorageTexelBufferArrayNonUniformIndexingEXT", 5312, 2, pygen_variable_caps_ImageBufferShaderNonUniform, 1, pygen_variable_exts_SPV_EXT_descriptor_indexing, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"RayTracingNV", 5340, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu},
+ {"RayTracingMotionBlurNV", 5341, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_NV_ray_tracing_motion_blur, {}, 0xffffffffu, 0xffffffffu},
{"VulkanMemoryModel", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanMemoryModelKHR", 5345, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
{"VulkanMemoryModelDeviceScope", 5346, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_vulkan_memory_model, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu},
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h
index 2f78258b276..981446b61a5 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h
@@ -310,7 +310,7 @@ typedef enum spv_ext_inst_type_t {
SPV_EXT_INST_TYPE_DEBUGINFO,
SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
- SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100,
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100,
// Multiple distinct extended instruction set types could return this
// value, if they are prefixed with NonSemantic. and are otherwise
@@ -660,6 +660,11 @@ SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetWorkgroupScalarBlockLayout(
SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetSkipBlockLayout(
spv_validator_options options, bool val);
+// Records whether or not the validator should allow the LocalSizeId
+// decoration where the environment otherwise would not allow it.
+SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowLocalSizeId(
+ spv_validator_options options, bool val);
+
// Creates an optimizer options object with default options. Returns a valid
// options object. The object remains valid until it is passed into
// |spvOptimizerOptionsDestroy|.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp
index 0c31a182798..8dfb46b7742 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp
@@ -115,6 +115,12 @@ class ValidatorOptions {
spvValidatorOptionsSetSkipBlockLayout(options_, val);
}
+ // Enables LocalSizeId decorations where the environment would not otherwise
+ // allow them.
+ void SetAllowLocalSizeId(bool val) {
+ spvValidatorOptionsSetAllowLocalSizeId(options_, val);
+ }
+
// Records whether or not the validator should relax the rules on pointer
// usage in logical addressing mode.
//
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp
index 57d1b4e9850..52ed5a46728 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp
@@ -35,7 +35,7 @@ class Linter {
void SetMessageConsumer(MessageConsumer consumer);
// Returns a reference to the registered message consumer.
- const MessageConsumer& consumer() const;
+ const MessageConsumer& Consumer() const;
bool Run(const uint32_t* binary, size_t binary_size);
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
index 700f59f70fd..42eb6442ec1 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp
@@ -19,6 +19,7 @@
#include <ostream>
#include <string>
#include <unordered_map>
+#include <utility>
#include <vector>
#include "libspirv.hpp"
@@ -27,7 +28,8 @@ namespace spvtools {
namespace opt {
class Pass;
-}
+struct DescriptorSetAndBinding;
+} // namespace opt
// C++ interface for SPIR-V optimization functionalities. It wraps the context
// (including target environment and the corresponding SPIR-V grammar) and
@@ -512,7 +514,12 @@ Optimizer::PassToken CreateDeadInsertElimPass();
// Conversion, which tends to cause cycles of dead code to be left after
// Store/Load elimination passes are completed. These cycles cannot be
// eliminated with standard dead code elimination.
-Optimizer::PassToken CreateAggressiveDCEPass();
+//
+// If |preserve_interface| is true, all non-io variables in the entry point
+// interface are considered live and are not eliminated. This mode is needed
+// by GPU-Assisted validation instrumentation, where a change in the interface
+// is not allowed.
+Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface = false);
// Creates a remove-unused-interface-variables pass.
// Removes variables referenced on the |OpEntryPoint| instruction that are not
@@ -699,8 +706,11 @@ Optimizer::PassToken CreateVectorDCEPass();
// Create a pass to reduce the size of loads.
// This pass looks for loads of structures where only a few of its members are
// used. It replaces the loads feeding an OpExtract with an OpAccessChain and
-// a load of the specific elements.
-Optimizer::PassToken CreateReduceLoadSizePass();
+// a load of the specific elements. The parameter is a threshold to determine
+// whether we have to replace the load or not. If the ratio of the used
+// components of the load is less than the threshold, we replace the load.
+Optimizer::PassToken CreateReduceLoadSizePass(
+ double load_replacement_threshold = 0.9);
// Create a pass to combine chained access chains.
// This pass looks for access chains fed by other access chains and combines
@@ -854,6 +864,16 @@ Optimizer::PassToken CreateAmdExtToKhrPass();
// propagated into their final positions.
Optimizer::PassToken CreateInterpolateFixupPass();
+// Creates a convert-to-sampled-image pass to convert images and/or
+// samplers with given pairs of descriptor set and binding to sampled image.
+// If a pair of an image and a sampler have the same pair of descriptor set and
+// binding that is one of the given pairs, they will be converted to a sampled
+// image. In addition, if only an image has the descriptor set and binding that
+// is one of the given pairs, it will be converted to a sampled image as well.
+Optimizer::PassToken CreateConvertToSampledImagePass(
+ const std::vector<opt::DescriptorSetAndBinding>&
+ descriptor_set_binding_pairs);
+
} // namespace spvtools
#endif // INCLUDE_SPIRV_TOOLS_OPTIMIZER_HPP_
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/binary.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/binary.cpp
index 090cccfecda..93d5da7aba7 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/binary.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/binary.cpp
@@ -507,7 +507,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset,
case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
assert(SpvOpSpecConstantOp == opcode);
- if (grammar_.lookupSpecConstantOpcode(SpvOp(word))) {
+ if (word > static_cast<uint32_t>(SpvOp::SpvOpMax) ||
+ grammar_.lookupSpecConstantOpcode(SpvOp(word))) {
return diagnostic()
<< "Invalid " << spvOperandTypeStr(type) << ": " << word;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/common_debug_info.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/common_debug_info.h
index 0ae85aa0606..ffa5d340c0c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/common_debug_info.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/common_debug_info.h
@@ -18,8 +18,8 @@
#define SOURCE_COMMON_DEBUG_INFO_HEADER_H_
// This enum defines the known common set of instructions that are the same
-// between OpenCL.DebugInfo.100 and NonSemantic.Vulkan.DebugInfo.100.
-// note that NonSemantic.DebugInfo.100 instructions can still have slightly
+// between OpenCL.DebugInfo.100 and NonSemantic.Shader.DebugInfo.100.
+// Note that NonSemantic.Shader.* instructions can still have slightly
// different encoding, as it does not use literals anywhere and only constants.
enum CommonDebugInfoInstructions {
CommonDebugInfoDebugInfoNone = 0,
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp
index f5f433162db..812053ec0ab 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp
@@ -29,7 +29,7 @@
#include "debuginfo.insts.inc"
#include "glsl.std.450.insts.inc"
#include "nonsemantic.clspvreflection.insts.inc"
-#include "nonsemantic.vulkan.debuginfo.100.insts.inc"
+#include "nonsemantic.shader.debuginfo.100.insts.inc"
#include "opencl.debuginfo.100.insts.inc"
#include "opencl.std.insts.inc"
@@ -56,9 +56,9 @@ static const spv_ext_inst_group_t kGroups_1_0[] = {
debuginfo_entries},
{SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
ARRAY_SIZE(opencl_debuginfo_100_entries), opencl_debuginfo_100_entries},
- {SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100,
- ARRAY_SIZE(nonsemantic_vulkan_debuginfo_100_entries),
- nonsemantic_vulkan_debuginfo_100_entries},
+ {SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100,
+ ARRAY_SIZE(nonsemantic_shader_debuginfo_100_entries),
+ nonsemantic_shader_debuginfo_100_entries},
{SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION,
ARRAY_SIZE(nonsemantic_clspvreflection_entries),
nonsemantic_clspvreflection_entries},
@@ -130,8 +130,8 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) {
if (!strcmp("OpenCL.DebugInfo.100", name)) {
return SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100;
}
- if (!strcmp("NonSemantic.Vulkan.DebugInfo.100", name)) {
- return SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100;
+ if (!strcmp("NonSemantic.Shader.DebugInfo.100", name)) {
+ return SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
}
if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) {
return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION;
@@ -146,7 +146,7 @@ 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_VULKAN_DEBUGINFO_100 ||
+ type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
return true;
}
@@ -155,6 +155,7 @@ bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) {
bool spvExtInstIsDebugInfo(const spv_ext_inst_type_t type) {
if (type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
+ type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
type == SPV_EXT_INST_TYPE_DEBUGINFO) {
return true;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json b/3rdparty/bgfx/3rdparty/spirv-tools/source/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json
deleted file mode 100644
index 371aa423280..00000000000
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json
+++ /dev/null
@@ -1,637 +0,0 @@
-{
- "copyright" : [
- "Copyright (c) 2018 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."
- ],
- "version" : 100,
- "revision" : 2,
- "instructions" : [
- {
- "opname" : "DebugInfoNone",
- "opcode" : 0
- },
- {
- "opname" : "DebugCompilationUnit",
- "opcode" : 1,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Version'" },
- { "kind" : "IdRef", "name" : "'DWARF Version'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Language'" }
- ]
- },
- {
- "opname" : "DebugTypeBasic",
- "opcode" : 2,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Size'" },
- { "kind" : "IdRef", "name" : "'Encoding'" }
- ]
- },
- {
- "opname" : "DebugTypePointer",
- "opcode" : 3,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Base Type'" },
- { "kind" : "IdRef", "name" : "'Storage Class'" },
- { "kind" : "IdRef", "name" : "'Flags'" }
- ]
- },
- {
- "opname" : "DebugTypeQualifier",
- "opcode" : 4,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Base Type'" },
- { "kind" : "IdRef", "name" : "'Type Qualifier'" }
- ]
- },
- {
- "opname" : "DebugTypeArray",
- "opcode" : 5,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Base Type'" },
- { "kind" : "IdRef", "name" : "'Component Counts'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugTypeVector",
- "opcode" : 6,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Base Type'" },
- { "kind" : "IdRef", "name" : "'Component Count'" }
- ]
- },
- {
- "opname" : "DebugTypedef",
- "opcode" : 7,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Base Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" }
- ]
- },
- {
- "opname" : "DebugTypeFunction",
- "opcode" : 8,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Return Type'" },
- { "kind" : "IdRef", "name" : "'Parameter Types'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugTypeEnum",
- "opcode" : 9,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Underlying Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Size'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "PairIdRefIdRef", "name" : "'Value, Name, Value, Name, ...'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugTypeComposite",
- "opcode" : 10,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Tag'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Linkage Name'" },
- { "kind" : "IdRef", "name" : "'Size'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Members'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugTypeMember",
- "opcode" : 11,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Offset'" },
- { "kind" : "IdRef", "name" : "'Size'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugTypeInheritance",
- "opcode" : 12,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Offset'" },
- { "kind" : "IdRef", "name" : "'Size'" },
- { "kind" : "IdRef", "name" : "'Flags'" }
- ]
- },
- {
- "opname" : "DebugTypePtrToMember",
- "opcode" : 13,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Member Type'" },
- { "kind" : "IdRef", "name" : "'Parent'" }
- ]
- },
- {
- "opname" : "DebugTypeTemplate",
- "opcode" : 14,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Target'" },
- { "kind" : "IdRef", "name" : "'Parameters'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugTypeTemplateParameter",
- "opcode" : 15,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Actual Type'" },
- { "kind" : "IdRef", "name" : "'Value'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" }
- ]
- },
- {
- "opname" : "DebugTypeTemplateTemplateParameter",
- "opcode" : 16,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Template Name'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" }
- ]
- },
- {
- "opname" : "DebugTypeTemplateParameterPack",
- "opcode" : 17,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Template Parameters'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugGlobalVariable",
- "opcode" : 18,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Linkage Name'" },
- { "kind" : "IdRef", "name" : "'Variable'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Static Member Declaration'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugFunctionDeclaration",
- "opcode" : 19,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Linkage Name'" },
- { "kind" : "IdRef", "name" : "'Flags'" }
- ]
- },
- {
- "opname" : "DebugFunction",
- "opcode" : 20,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Linkage Name'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Scope Line'" },
- { "kind" : "IdRef", "name" : "'Declaration'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugLexicalBlock",
- "opcode" : 21,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Name'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugLexicalBlockDiscriminator",
- "opcode" : 22,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Discriminator'" },
- { "kind" : "IdRef", "name" : "'Parent'" }
- ]
- },
- {
- "opname" : "DebugScope",
- "opcode" : 23,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Scope'" },
- { "kind" : "IdRef", "name" : "'Inlined At'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugNoScope",
- "opcode" : 24
- },
- {
- "opname" : "DebugInlinedAt",
- "opcode" : 25,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Scope'" },
- { "kind" : "IdRef", "name" : "'Inlined'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugLocalVariable",
- "opcode" : 26,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Type'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" },
- { "kind" : "IdRef", "name" : "'Flags'" },
- { "kind" : "IdRef", "name" : "'Arg Number'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugInlinedVariable",
- "opcode" : 27,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Variable'" },
- { "kind" : "IdRef", "name" : "'Inlined'" }
- ]
- },
- {
- "opname" : "DebugDeclare",
- "opcode" : 28,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Local Variable'" },
- { "kind" : "IdRef", "name" : "'Variable'" },
- { "kind" : "IdRef", "name" : "'Expression'" }
- ]
- },
- {
- "opname" : "DebugValue",
- "opcode" : 29,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Local Variable'" },
- { "kind" : "IdRef", "name" : "'Value'" },
- { "kind" : "IdRef", "name" : "'Expression'" },
- { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugOperation",
- "opcode" : 30,
- "operands" : [
- { "kind" : "IdRef", "name" : "'OpCode'" },
- { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugExpression",
- "opcode" : 31,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Operands ...'", "quantifier" : "*" }
- ]
- },
- {
- "opname" : "DebugMacroDef",
- "opcode" : 32,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Value'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugMacroUndef",
- "opcode" : 33,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Macro'" }
- ]
- },
- {
- "opname" : "DebugImportedEntity",
- "opcode" : 34,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Name'" },
- { "kind" : "IdRef", "name" : "'Tag'" },
- { "kind" : "IdRef", "name" : "'Source'" },
- { "kind" : "IdRef", "name" : "'Entity'" },
- { "kind" : "IdRef", "name" : "'Line'" },
- { "kind" : "IdRef", "name" : "'Column'" },
- { "kind" : "IdRef", "name" : "'Parent'" }
- ]
- },
- {
- "opname" : "DebugSource",
- "opcode" : 35,
- "operands" : [
- { "kind" : "IdRef", "name" : "'File'" },
- { "kind" : "IdRef", "name" : "'Text'", "quantifier" : "?" }
- ]
- },
- {
- "opname" : "DebugFunctionDefinition",
- "opcode" : 101,
- "operands" : [
- { "kind" : "IdRef", "name" : "'Function'" },
- { "kind" : "IdRef", "name" : "'Definition'" }
- ]
- }
- ],
- "operand_kinds" : [
- {
- "category" : "BitEnum",
- "kind" : "DebugInfoFlags",
- "enumerants" : [
- {
- "enumerant" : "FlagIsProtected",
- "value" : "0x01"
- },
- {
- "enumerant" : "FlagIsPrivate",
- "value" : "0x02"
- },
- {
- "enumerant" : "FlagIsPublic",
- "value" : "0x03"
- },
- {
- "enumerant" : "FlagIsLocal",
- "value" : "0x04"
- },
- {
- "enumerant" : "FlagIsDefinition",
- "value" : "0x08"
- },
- {
- "enumerant" : "FlagFwdDecl",
- "value" : "0x10"
- },
- {
- "enumerant" : "FlagArtificial",
- "value" : "0x20"
- },
- {
- "enumerant" : "FlagExplicit",
- "value" : "0x40"
- },
- {
- "enumerant" : "FlagPrototyped",
- "value" : "0x80"
- },
- {
- "enumerant" : "FlagObjectPointer",
- "value" : "0x100"
- },
- {
- "enumerant" : "FlagStaticMember",
- "value" : "0x200"
- },
- {
- "enumerant" : "FlagIndirectVariable",
- "value" : "0x400"
- },
- {
- "enumerant" : "FlagLValueReference",
- "value" : "0x800"
- },
- {
- "enumerant" : "FlagRValueReference",
- "value" : "0x1000"
- },
- {
- "enumerant" : "FlagIsOptimized",
- "value" : "0x2000"
- },
- {
- "enumerant" : "FlagIsEnumClass",
- "value" : "0x4000"
- },
- {
- "enumerant" : "FlagTypePassByValue",
- "value" : "0x8000"
- },
- {
- "enumerant" : "FlagTypePassByReference",
- "value" : "0x10000"
- }
- ]
- },
- {
- "category" : "ValueEnum",
- "kind" : "DebugBaseTypeAttributeEncoding",
- "enumerants" : [
- {
- "enumerant" : "Unspecified",
- "value" : "0"
- },
- {
- "enumerant" : "Address",
- "value" : "1"
- },
- {
- "enumerant" : "Boolean",
- "value" : "2"
- },
- {
- "enumerant" : "Float",
- "value" : "3"
- },
- {
- "enumerant" : "Signed",
- "value" : "4"
- },
- {
- "enumerant" : "SignedChar",
- "value" : "5"
- },
- {
- "enumerant" : "Unsigned",
- "value" : "6"
- },
- {
- "enumerant" : "UnsignedChar",
- "value" : "7"
- }
- ]
- },
- {
- "category" : "ValueEnum",
- "kind" : "DebugCompositeType",
- "enumerants" : [
- {
- "enumerant" : "Class",
- "value" : "0"
- },
- {
- "enumerant" : "Structure",
- "value" : "1"
- },
- {
- "enumerant" : "Union",
- "value" : "2"
- }
- ]
- },
- {
- "category" : "ValueEnum",
- "kind" : "DebugTypeQualifier",
- "enumerants" : [
- {
- "enumerant" : "ConstType",
- "value" : "0"
- },
- {
- "enumerant" : "VolatileType",
- "value" : "1"
- },
- {
- "enumerant" : "RestrictType",
- "value" : "2"
- },
- {
- "enumerant" : "AtomicType",
- "value" : "3"
- }
- ]
- },
- {
- "category" : "ValueEnum",
- "kind" : "DebugOperation",
- "enumerants" : [
- {
- "enumerant" : "Deref",
- "value" : "0"
- },
- {
- "enumerant" : "Plus",
- "value" : "1"
- },
- {
- "enumerant" : "Minus",
- "value" : "2"
- },
- {
- "enumerant" : "PlusUconst",
- "value" : "3",
- "parameters" : [
- { "kind" : "IdRef" }
- ]
- },
- {
- "enumerant" : "BitPiece",
- "value" : "4",
- "parameters" : [
- { "kind" : "IdRef" },
- { "kind" : "IdRef" }
- ]
- },
- {
- "enumerant" : "Swap",
- "value" : "5"
- },
- {
- "enumerant" : "Xderef",
- "value" : "6"
- },
- {
- "enumerant" : "StackValue",
- "value" : "7"
- },
- {
- "enumerant" : "Constu",
- "value" : "8",
- "parameters" : [
- { "kind" : "IdRef" }
- ]
- },
- {
- "enumerant" : "Fragment",
- "value" : "9",
- "parameters" : [
- { "kind" : "IdRef" },
- { "kind" : "IdRef" }
- ]
- }
- ]
- },
- {
- "category" : "ValueEnum",
- "kind" : "DebugImportedEntity",
- "enumerants" : [
- {
- "enumerant" : "ImportedModule",
- "value" : "0"
- },
- {
- "enumerant" : "ImportedDeclaration",
- "value" : "1"
- }
- ]
- }
- ]
-}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp
new file mode 100644
index 00000000000..b5a72b459db
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp
@@ -0,0 +1,245 @@
+// Copyright (c) 2021 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 "source/lint/divergence_analysis.h"
+
+#include "source/opt/basic_block.h"
+#include "source/opt/control_dependence.h"
+#include "source/opt/dataflow.h"
+#include "source/opt/function.h"
+#include "source/opt/instruction.h"
+#include "spirv/unified1/spirv.h"
+
+namespace spvtools {
+namespace lint {
+
+void DivergenceAnalysis::EnqueueSuccessors(opt::Instruction* inst) {
+ // Enqueue control dependents of block, if applicable.
+ // There are two ways for a dependence source to be updated:
+ // 1. control -> control: source block is marked divergent.
+ // 2. data -> control: branch condition is marked divergent.
+ uint32_t block_id;
+ if (inst->IsBlockTerminator()) {
+ block_id = context().get_instr_block(inst)->id();
+ } else if (inst->opcode() == SpvOpLabel) {
+ block_id = inst->result_id();
+ opt::BasicBlock* bb = context().cfg()->block(block_id);
+ // Only enqueue phi instructions, as other uses don't affect divergence.
+ bb->ForEachPhiInst([this](opt::Instruction* phi) { Enqueue(phi); });
+ } else {
+ opt::ForwardDataFlowAnalysis::EnqueueUsers(inst);
+ return;
+ }
+ if (!cd_.HasBlock(block_id)) {
+ return;
+ }
+ for (const spvtools::opt::ControlDependence& dep :
+ cd_.GetDependenceTargets(block_id)) {
+ opt::Instruction* target_inst =
+ context().cfg()->block(dep.target_bb_id())->GetLabelInst();
+ Enqueue(target_inst);
+ }
+}
+
+opt::DataFlowAnalysis::VisitResult DivergenceAnalysis::Visit(
+ opt::Instruction* inst) {
+ if (inst->opcode() == SpvOpLabel) {
+ return VisitBlock(inst->result_id());
+ } else {
+ return VisitInstruction(inst);
+ }
+}
+
+opt::DataFlowAnalysis::VisitResult DivergenceAnalysis::VisitBlock(uint32_t id) {
+ if (!cd_.HasBlock(id)) {
+ return opt::DataFlowAnalysis::VisitResult::kResultFixed;
+ }
+ DivergenceLevel& cur_level = divergence_[id];
+ if (cur_level == DivergenceLevel::kDivergent) {
+ return opt::DataFlowAnalysis::VisitResult::kResultFixed;
+ }
+ DivergenceLevel orig = cur_level;
+ for (const spvtools::opt::ControlDependence& dep :
+ cd_.GetDependenceSources(id)) {
+ if (divergence_[dep.source_bb_id()] > cur_level) {
+ cur_level = divergence_[dep.source_bb_id()];
+ divergence_source_[id] = dep.source_bb_id();
+ } else if (dep.source_bb_id() != 0) {
+ uint32_t condition_id = dep.GetConditionID(*context().cfg());
+ DivergenceLevel dep_level = divergence_[condition_id];
+ // Check if we are along the chain of unconditional branches starting from
+ // the branch target.
+ if (follow_unconditional_branches_[dep.branch_target_bb_id()] !=
+ follow_unconditional_branches_[dep.target_bb_id()]) {
+ // We must have reconverged in order to reach this block.
+ // Promote partially uniform to divergent.
+ if (dep_level == DivergenceLevel::kPartiallyUniform) {
+ dep_level = DivergenceLevel::kDivergent;
+ }
+ }
+ if (dep_level > cur_level) {
+ cur_level = dep_level;
+ divergence_source_[id] = condition_id;
+ divergence_dependence_source_[id] = dep.source_bb_id();
+ }
+ }
+ }
+ return cur_level > orig ? VisitResult::kResultChanged
+ : VisitResult::kResultFixed;
+}
+
+opt::DataFlowAnalysis::VisitResult DivergenceAnalysis::VisitInstruction(
+ opt::Instruction* inst) {
+ if (inst->IsBlockTerminator()) {
+ // This is called only when the condition has changed, so return changed.
+ return VisitResult::kResultChanged;
+ }
+ if (!inst->HasResultId()) {
+ return VisitResult::kResultFixed;
+ }
+ uint32_t id = inst->result_id();
+ DivergenceLevel& cur_level = divergence_[id];
+ if (cur_level == DivergenceLevel::kDivergent) {
+ return opt::DataFlowAnalysis::VisitResult::kResultFixed;
+ }
+ DivergenceLevel orig = cur_level;
+ cur_level = ComputeInstructionDivergence(inst);
+ return cur_level > orig ? VisitResult::kResultChanged
+ : VisitResult::kResultFixed;
+}
+
+DivergenceAnalysis::DivergenceLevel
+DivergenceAnalysis::ComputeInstructionDivergence(opt::Instruction* inst) {
+ // TODO(kuhar): Check to see if inst is decorated with Uniform or UniformId
+ // and use that to short circuit other checks. Uniform is for subgroups which
+ // would satisfy derivative groups too. UniformId takes a scope, so if it is
+ // subgroup or greater it could satisfy derivative group and
+ // Device/QueueFamily could satisfy fully uniform.
+ uint32_t id = inst->result_id();
+ // Handle divergence roots.
+ if (inst->opcode() == SpvOpFunctionParameter) {
+ divergence_source_[id] = 0;
+ return divergence_[id] = DivergenceLevel::kDivergent;
+ } else if (inst->IsLoad()) {
+ spvtools::opt::Instruction* var = inst->GetBaseAddress();
+ if (var->opcode() != SpvOpVariable) {
+ // Assume divergent.
+ divergence_source_[id] = 0;
+ return DivergenceLevel::kDivergent;
+ }
+ DivergenceLevel ret = ComputeVariableDivergence(var);
+ if (ret > DivergenceLevel::kUniform) {
+ divergence_source_[inst->result_id()] = 0;
+ }
+ return divergence_[id] = ret;
+ }
+ // Get the maximum divergence of the operands.
+ DivergenceLevel ret = DivergenceLevel::kUniform;
+ inst->ForEachInId([this, inst, &ret](const uint32_t* op) {
+ if (!op) return;
+ if (divergence_[*op] > ret) {
+ divergence_source_[inst->result_id()] = *op;
+ ret = divergence_[*op];
+ }
+ });
+ divergence_[inst->result_id()] = ret;
+ return ret;
+}
+
+DivergenceAnalysis::DivergenceLevel
+DivergenceAnalysis::ComputeVariableDivergence(opt::Instruction* var) {
+ uint32_t type_id = var->type_id();
+ spvtools::opt::analysis::Pointer* type =
+ context().get_type_mgr()->GetType(type_id)->AsPointer();
+ assert(type != nullptr);
+ uint32_t def_id = var->result_id();
+ DivergenceLevel ret;
+ switch (type->storage_class()) {
+ case SpvStorageClassFunction:
+ case SpvStorageClassGeneric:
+ case SpvStorageClassAtomicCounter:
+ case SpvStorageClassStorageBuffer:
+ case SpvStorageClassPhysicalStorageBuffer:
+ case SpvStorageClassOutput:
+ case SpvStorageClassWorkgroup:
+ case SpvStorageClassImage: // Image atomics probably aren't uniform.
+ case SpvStorageClassPrivate:
+ ret = DivergenceLevel::kDivergent;
+ break;
+ case SpvStorageClassInput:
+ ret = DivergenceLevel::kDivergent;
+ // If this variable has a Flat decoration, it is partially uniform.
+ // TODO(kuhar): Track access chain indices and also consider Flat members
+ // of a structure.
+ context().get_decoration_mgr()->WhileEachDecoration(
+ def_id, SpvDecorationFlat, [&ret](const opt::Instruction&) {
+ ret = DivergenceLevel::kPartiallyUniform;
+ return false;
+ });
+ break;
+ case SpvStorageClassUniformConstant:
+ // May be a storage image which is also written to; mark those as
+ // divergent.
+ if (!var->IsVulkanStorageImage() || var->IsReadOnlyPointer()) {
+ ret = DivergenceLevel::kUniform;
+ } else {
+ ret = DivergenceLevel::kDivergent;
+ }
+ break;
+ case SpvStorageClassUniform:
+ case SpvStorageClassPushConstant:
+ case SpvStorageClassCrossWorkgroup: // Not for shaders; default uniform.
+ default:
+ ret = DivergenceLevel::kUniform;
+ break;
+ }
+ return ret;
+}
+
+void DivergenceAnalysis::Setup(opt::Function* function) {
+ // TODO(kuhar): Run functions called by |function| so we can detect
+ // reconvergence caused by multiple returns.
+ cd_.ComputeControlDependenceGraph(
+ *context().cfg(), *context().GetPostDominatorAnalysis(function));
+ context().cfg()->ForEachBlockInPostOrder(
+ function->entry().get(), [this](const opt::BasicBlock* bb) {
+ uint32_t id = bb->id();
+ if (bb->terminator() == nullptr ||
+ bb->terminator()->opcode() != SpvOpBranch) {
+ follow_unconditional_branches_[id] = id;
+ } else {
+ uint32_t target_id = bb->terminator()->GetSingleWordInOperand(0);
+ // Target is guaranteed to have been visited before us in postorder.
+ follow_unconditional_branches_[id] =
+ follow_unconditional_branches_[target_id];
+ }
+ });
+}
+
+std::ostream& operator<<(std::ostream& os,
+ DivergenceAnalysis::DivergenceLevel level) {
+ switch (level) {
+ case DivergenceAnalysis::DivergenceLevel::kUniform:
+ return os << "uniform";
+ case DivergenceAnalysis::DivergenceLevel::kPartiallyUniform:
+ return os << "partially uniform";
+ case DivergenceAnalysis::DivergenceLevel::kDivergent:
+ return os << "divergent";
+ default:
+ return os << "<invalid divergence level>";
+ }
+}
+
+} // namespace lint
+} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.h
new file mode 100644
index 00000000000..4d595ec2828
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.h
@@ -0,0 +1,163 @@
+// Copyright (c) 2021 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 SOURCE_LINT_DIVERGENCE_ANALYSIS_H_
+#define SOURCE_LINT_DIVERGENCE_ANALYSIS_H_
+
+#include <cstdint>
+#include <ostream>
+#include <unordered_map>
+
+#include "source/opt/basic_block.h"
+#include "source/opt/control_dependence.h"
+#include "source/opt/dataflow.h"
+#include "source/opt/function.h"
+#include "source/opt/instruction.h"
+
+namespace spvtools {
+namespace lint {
+
+// Computes the static divergence level for blocks (control flow) and values.
+//
+// A value is uniform if all threads that execute it are guaranteed to have the
+// same value. Similarly, a value is partially uniform if this is true only
+// within each derivative group. If neither apply, it is divergent.
+//
+// Control flow through a block is uniform if for any possible execution and
+// point in time, all threads are executing it, or no threads are executing it.
+// In particular, it is never possible for some threads to be inside the block
+// and some threads not executing.
+// TODO(kuhar): Clarify the difference between uniform, divergent, and
+// partially-uniform execution in this analysis.
+//
+// Caveat:
+// As we use control dependence to determine how divergence is propagated, this
+// analysis can be overly permissive when the merge block for a conditional
+// branch or switch is later than (strictly postdominates) the expected merge
+// block, which is the immediate postdominator. However, this is not expected to
+// be a problem in practice, given that SPIR-V is generally output by compilers
+// and other automated tools, which would assign the earliest possible merge
+// block, rather than written by hand.
+// TODO(kuhar): Handle late merges.
+class DivergenceAnalysis : public opt::ForwardDataFlowAnalysis {
+ public:
+ // The tightest (most uniform) level of divergence that can be determined
+ // statically for a value or control flow for a block.
+ //
+ // The values are ordered such that A > B means that A is potentially more
+ // divergent than B.
+ // TODO(kuhar): Rename |PartiallyUniform' to something less confusing. For
+ // example, the enum could be based on scopes.
+ enum class DivergenceLevel {
+ // The value or control flow is uniform across the entire invocation group.
+ kUniform = 0,
+ // The value or control flow is uniform across the derivative group, but not
+ // the invocation group.
+ kPartiallyUniform = 1,
+ // The value or control flow is not statically uniform.
+ kDivergent = 2,
+ };
+
+ DivergenceAnalysis(opt::IRContext& context)
+ : ForwardDataFlowAnalysis(context, LabelPosition::kLabelsAtEnd) {}
+
+ // Returns the divergence level for the given value (non-label instructions),
+ // or control flow for the given block.
+ DivergenceLevel GetDivergenceLevel(uint32_t id) {
+ auto it = divergence_.find(id);
+ if (it == divergence_.end()) {
+ return DivergenceLevel::kUniform;
+ }
+ return it->second;
+ }
+
+ // Returns the divergence source for the given id. The following types of
+ // divergence flows from A to B are possible:
+ //
+ // data -> data: A is used as an operand in the definition of B.
+ // data -> control: B is control-dependent on a branch with condition A.
+ // control -> data: B is a OpPhi instruction in which A is a block operand.
+ // control -> control: B is control-dependent on A.
+ uint32_t GetDivergenceSource(uint32_t id) {
+ auto it = divergence_source_.find(id);
+ if (it == divergence_source_.end()) {
+ return 0;
+ }
+ return it->second;
+ }
+
+ // Returns the dependence source for the control dependence for the given id.
+ // This only exists for data -> control edges.
+ //
+ // In other words, if block 2 is dependent on block 1 due to value 3 (e.g.
+ // block 1 terminates with OpBranchConditional %3 %2 %4):
+ // * GetDivergenceSource(2) = 3
+ // * GetDivergenceDependenceSource(2) = 1
+ //
+ // Returns 0 if not applicable.
+ uint32_t GetDivergenceDependenceSource(uint32_t id) {
+ auto it = divergence_dependence_source_.find(id);
+ if (it == divergence_dependence_source_.end()) {
+ return 0;
+ }
+ return it->second;
+ }
+
+ void InitializeWorklist(opt::Function* function,
+ bool is_first_iteration) override {
+ // Since |EnqueueSuccessors| is complete, we only need one pass.
+ if (is_first_iteration) {
+ Setup(function);
+ opt::ForwardDataFlowAnalysis::InitializeWorklist(function, true);
+ }
+ }
+
+ void EnqueueSuccessors(opt::Instruction* inst) override;
+
+ VisitResult Visit(opt::Instruction* inst) override;
+
+ private:
+ VisitResult VisitBlock(uint32_t id);
+ VisitResult VisitInstruction(opt::Instruction* inst);
+
+ // Computes the divergence level for the result of the given instruction
+ // based on the current state of the analysis. This is always an
+ // underapproximation, which will be improved as the analysis proceeds.
+ DivergenceLevel ComputeInstructionDivergence(opt::Instruction* inst);
+
+ // Computes the divergence level for a variable, which is used for loads.
+ DivergenceLevel ComputeVariableDivergence(opt::Instruction* var);
+
+ // Initializes data structures for performing dataflow on the given function.
+ void Setup(opt::Function* function);
+
+ std::unordered_map<uint32_t, DivergenceLevel> divergence_;
+ std::unordered_map<uint32_t, uint32_t> divergence_source_;
+ std::unordered_map<uint32_t, uint32_t> divergence_dependence_source_;
+
+ // Stores the result of following unconditional branches starting from the
+ // given block. This is used to detect when reconvergence needs to be
+ // accounted for.
+ std::unordered_map<uint32_t, uint32_t> follow_unconditional_branches_;
+
+ opt::ControlDependenceAnalysis cd_;
+};
+
+std::ostream& operator<<(std::ostream& os,
+ DivergenceAnalysis::DivergenceLevel level);
+
+} // namespace lint
+} // namespace spvtools
+
+#endif // SOURCE_LINT_DIVERGENCE_ANALYSIS_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp
new file mode 100644
index 00000000000..512847b0cec
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp
@@ -0,0 +1,169 @@
+// Copyright (c) 2021 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 <cassert>
+#include <sstream>
+#include <string>
+
+#include "source/diagnostic.h"
+#include "source/lint/divergence_analysis.h"
+#include "source/lint/lints.h"
+#include "source/opt/basic_block.h"
+#include "source/opt/cfg.h"
+#include "source/opt/control_dependence.h"
+#include "source/opt/def_use_manager.h"
+#include "source/opt/dominator_analysis.h"
+#include "source/opt/instruction.h"
+#include "source/opt/ir_context.h"
+#include "spirv-tools/libspirv.h"
+#include "spirv/unified1/spirv.h"
+
+namespace spvtools {
+namespace lint {
+namespace lints {
+namespace {
+// Returns the %name[id], where `name` is the first name associated with the
+// given id, or just %id if one is not found.
+std::string GetFriendlyName(opt::IRContext* context, uint32_t id) {
+ auto names = context->GetNames(id);
+ std::stringstream ss;
+ ss << "%";
+ if (names.empty()) {
+ ss << id;
+ } else {
+ opt::Instruction* inst_name = names.begin()->second;
+ if (inst_name->opcode() == SpvOpName) {
+ ss << names.begin()->second->GetInOperand(0).AsString();
+ ss << "[" << id << "]";
+ } else {
+ ss << id;
+ }
+ }
+ return ss.str();
+}
+
+bool InstructionHasDerivative(const opt::Instruction& inst) {
+ static const SpvOp derivative_opcodes[] = {
+ // Implicit derivatives.
+ SpvOpImageSampleImplicitLod,
+ SpvOpImageSampleDrefImplicitLod,
+ SpvOpImageSampleProjImplicitLod,
+ SpvOpImageSampleProjDrefImplicitLod,
+ SpvOpImageSparseSampleImplicitLod,
+ SpvOpImageSparseSampleDrefImplicitLod,
+ SpvOpImageSparseSampleProjImplicitLod,
+ SpvOpImageSparseSampleProjDrefImplicitLod,
+ // Explicit derivatives.
+ SpvOpDPdx,
+ SpvOpDPdy,
+ SpvOpFwidth,
+ SpvOpDPdxFine,
+ SpvOpDPdyFine,
+ SpvOpFwidthFine,
+ SpvOpDPdxCoarse,
+ SpvOpDPdyCoarse,
+ SpvOpFwidthCoarse,
+ };
+ return std::find(std::begin(derivative_opcodes), std::end(derivative_opcodes),
+ inst.opcode()) != std::end(derivative_opcodes);
+}
+
+spvtools::DiagnosticStream Warn(opt::IRContext* context,
+ opt::Instruction* inst) {
+ if (inst == nullptr) {
+ return DiagnosticStream({0, 0, 0}, context->consumer(), "", SPV_WARNING);
+ } else {
+ // TODO(kuhar): Use line numbers based on debug info.
+ return DiagnosticStream(
+ {0, 0, 0}, context->consumer(),
+ inst->PrettyPrint(SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES),
+ SPV_WARNING);
+ }
+}
+
+void PrintDivergenceFlow(opt::IRContext* context, DivergenceAnalysis div,
+ uint32_t id) {
+ opt::analysis::DefUseManager* def_use = context->get_def_use_mgr();
+ opt::CFG* cfg = context->cfg();
+ while (id != 0) {
+ bool is_block = def_use->GetDef(id)->opcode() == SpvOpLabel;
+ if (is_block) {
+ Warn(context, nullptr)
+ << "block " << GetFriendlyName(context, id) << " is divergent";
+ uint32_t source = div.GetDivergenceSource(id);
+ // Skip intermediate blocks.
+ while (source != 0 && def_use->GetDef(source)->opcode() == SpvOpLabel) {
+ id = source;
+ source = div.GetDivergenceSource(id);
+ }
+ if (source == 0) break;
+ spvtools::opt::Instruction* branch =
+ cfg->block(div.GetDivergenceDependenceSource(id))->terminator();
+ Warn(context, branch)
+ << "because it depends on a conditional branch on divergent value "
+ << GetFriendlyName(context, source) << "";
+ id = source;
+ } else {
+ Warn(context, nullptr)
+ << "value " << GetFriendlyName(context, id) << " is divergent";
+ uint32_t source = div.GetDivergenceSource(id);
+ opt::Instruction* def = def_use->GetDef(id);
+ opt::Instruction* source_def =
+ source == 0 ? nullptr : def_use->GetDef(source);
+ // First print data -> data dependencies.
+ while (source != 0 && source_def->opcode() != SpvOpLabel) {
+ Warn(context, def_use->GetDef(id))
+ << "because " << GetFriendlyName(context, id) << " uses value "
+ << GetFriendlyName(context, source)
+ << "in its definition, which is divergent";
+ id = source;
+ def = source_def;
+ source = div.GetDivergenceSource(id);
+ source_def = def_use->GetDef(source);
+ }
+ if (source == 0) {
+ Warn(context, def) << "because it has a divergent definition";
+ break;
+ }
+ Warn(context, def) << "because it is conditionally set in block "
+ << GetFriendlyName(context, source);
+ id = source;
+ }
+ }
+}
+} // namespace
+
+bool CheckDivergentDerivatives(opt::IRContext* context) {
+ DivergenceAnalysis div(*context);
+ for (opt::Function& func : *context->module()) {
+ div.Run(&func);
+ for (const opt::BasicBlock& bb : func) {
+ for (const opt::Instruction& inst : bb) {
+ if (InstructionHasDerivative(inst) &&
+ div.GetDivergenceLevel(bb.id()) >
+ DivergenceAnalysis::DivergenceLevel::kPartiallyUniform) {
+ Warn(context, nullptr)
+ << "derivative with divergent control flow"
+ << " located in block " << GetFriendlyName(context, bb.id());
+ PrintDivergenceFlow(context, div, bb.id());
+ }
+ }
+ }
+ }
+ return true;
+}
+
+} // namespace lints
+} // namespace lint
+} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/linter.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/linter.cpp
index 0f8479537c5..e4ed04ea440 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/linter.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/linter.cpp
@@ -14,6 +14,13 @@
#include "spirv-tools/linter.hpp"
+#include "source/lint/lints.h"
+#include "source/opt/build_module.h"
+#include "source/opt/ir_context.h"
+#include "spirv-tools/libspirv.h"
+#include "spirv-tools/libspirv.hpp"
+#include "spirv/unified1/spirv.h"
+
namespace spvtools {
struct Linter::Impl {
@@ -32,20 +39,22 @@ Linter::Linter(spv_target_env env) : impl_(new Impl(env)) {}
Linter::~Linter() {}
void Linter::SetMessageConsumer(MessageConsumer consumer) {
- impl_->message_consumer = consumer;
+ impl_->message_consumer = std::move(consumer);
}
-const MessageConsumer& Linter::consumer() const {
+const MessageConsumer& Linter::Consumer() const {
return impl_->message_consumer;
}
bool Linter::Run(const uint32_t* binary, size_t binary_size) {
- (void)binary;
- (void)binary_size;
+ std::unique_ptr<opt::IRContext> context =
+ BuildModule(SPV_ENV_VULKAN_1_2, Consumer(), binary, binary_size);
+ if (context == nullptr) return false;
- consumer()(SPV_MSG_INFO, "", {0, 0, 0}, "Hello, world!");
+ bool result = true;
+ result &= lint::lints::CheckDivergentDerivatives(context.get());
- return true;
+ return result;
}
} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lints.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lints.h
new file mode 100644
index 00000000000..a1995d2fb75
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lints.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2021 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 SOURCE_LINT_LINTS_H_
+#define SOURCE_LINT_LINTS_H_
+
+#include "source/opt/ir_context.h"
+
+namespace spvtools {
+namespace lint {
+
+// All of the functions in this namespace output to the error consumer in the
+// |context| argument and return |true| if no errors are found. They do not
+// modify the IR.
+namespace lints {
+
+bool CheckDivergentDerivatives(opt::IRContext* context);
+
+} // namespace lints
+} // namespace lint
+} // namespace spvtools
+
+#endif // SOURCE_LINT_LINTS_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/operand.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/operand.cpp
index bff36a26999..6d83e81e2fe 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/operand.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/operand.cpp
@@ -579,8 +579,8 @@ std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
std::function<bool(unsigned)> spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
spv_ext_inst_type_t ext_type, uint32_t key) {
// The Vulkan debug info extended instruction set is non-semantic so allows no
- // forward references ever.
- if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100) {
+ // forward references ever
+ if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
return [](unsigned) { return false; };
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp
index 90d30e9a4ae..ac90fd3434f 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.cpp
@@ -35,7 +35,6 @@ namespace {
const uint32_t kTypePointerStorageClassInIdx = 0;
const uint32_t kEntryPointFunctionIdInIdx = 1;
const uint32_t kSelectionMergeMergeBlockIdInIdx = 0;
-const uint32_t kLoopMergeMergeBlockIdInIdx = 0;
const uint32_t kLoopMergeContinueBlockIdInIdx = 1;
const uint32_t kCopyMemoryTargetAddrInIdx = 0;
const uint32_t kCopyMemorySourceAddrInIdx = 1;
@@ -145,14 +144,26 @@ bool AggressiveDCEPass::AllExtensionsSupported() const {
if (extensions_allowlist_.find(extName) == extensions_allowlist_.end())
return false;
}
+ // Only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise
+ // around unknown extended instruction sets even if they are non-semantic
+ for (auto& inst : context()->module()->ext_inst_imports()) {
+ assert(inst.opcode() == SpvOpExtInstImport &&
+ "Expecting an import of an extension's instruction set.");
+ const char* extension_name =
+ reinterpret_cast<const char*>(&inst.GetInOperand(0).words[0]);
+ if (0 == std::strncmp(extension_name, "NonSemantic.", 12) &&
+ 0 != std::strncmp(extension_name, "NonSemantic.Shader.DebugInfo.100",
+ 32)) {
+ return false;
+ }
+ }
return true;
}
bool AggressiveDCEPass::IsDead(Instruction* inst) {
if (IsLive(inst)) return false;
if ((inst->IsBranch() || inst->opcode() == SpvOpUnreachable) &&
- !IsStructuredHeader(context()->get_instr_block(inst), nullptr, nullptr,
- nullptr))
+ context()->get_instr_block(inst)->GetMergeInst() == nullptr)
return false;
return true;
}
@@ -187,66 +198,6 @@ void AggressiveDCEPass::ProcessLoad(Function* func, uint32_t varId) {
live_local_vars_.insert(varId);
}
-bool AggressiveDCEPass::IsStructuredHeader(BasicBlock* bp,
- Instruction** mergeInst,
- Instruction** branchInst,
- uint32_t* mergeBlockId) {
- if (!bp) return false;
- Instruction* mi = bp->GetMergeInst();
- if (mi == nullptr) return false;
- Instruction* bri = &*bp->tail();
- if (branchInst != nullptr) *branchInst = bri;
- if (mergeInst != nullptr) *mergeInst = mi;
- if (mergeBlockId != nullptr) *mergeBlockId = mi->GetSingleWordInOperand(0);
- return true;
-}
-
-void AggressiveDCEPass::ComputeBlock2HeaderMaps(
- std::list<BasicBlock*>& structuredOrder) {
- block2headerBranch_.clear();
- header2nextHeaderBranch_.clear();
- branch2merge_.clear();
- structured_order_index_.clear();
- std::stack<Instruction*> currentHeaderBranch;
- currentHeaderBranch.push(nullptr);
- uint32_t currentMergeBlockId = 0;
- uint32_t index = 0;
- for (auto bi = structuredOrder.begin(); bi != structuredOrder.end();
- ++bi, ++index) {
- structured_order_index_[*bi] = index;
- // If this block is the merge block of the current control construct,
- // we are leaving the current construct so we must update state
- if ((*bi)->id() == currentMergeBlockId) {
- currentHeaderBranch.pop();
- Instruction* chb = currentHeaderBranch.top();
- if (chb != nullptr)
- currentMergeBlockId = branch2merge_[chb]->GetSingleWordInOperand(0);
- }
- Instruction* mergeInst;
- Instruction* branchInst;
- uint32_t mergeBlockId;
- bool is_header =
- IsStructuredHeader(*bi, &mergeInst, &branchInst, &mergeBlockId);
- // Map header block to next enclosing header.
- if (is_header) header2nextHeaderBranch_[*bi] = currentHeaderBranch.top();
- // If this is a loop header, update state first so the block will map to
- // itself.
- if (is_header && mergeInst->opcode() == SpvOpLoopMerge) {
- currentHeaderBranch.push(branchInst);
- branch2merge_[branchInst] = mergeInst;
- currentMergeBlockId = mergeBlockId;
- }
- // Map the block to the current construct.
- block2headerBranch_[*bi] = currentHeaderBranch.top();
- // If this is an if header, update state so following blocks map to the if.
- if (is_header && mergeInst->opcode() == SpvOpSelectionMerge) {
- currentHeaderBranch.push(branchInst);
- branch2merge_[branchInst] = mergeInst;
- currentMergeBlockId = mergeBlockId;
- }
- }
-}
-
void AggressiveDCEPass::AddBranch(uint32_t labelId, BasicBlock* bp) {
std::unique_ptr<Instruction> newBranch(
new Instruction(context(), SpvOpBranch, 0, 0,
@@ -262,23 +213,18 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
mergeInst->opcode() == SpvOpLoopMerge);
BasicBlock* header = context()->get_instr_block(mergeInst);
- uint32_t headerIndex = structured_order_index_[header];
const uint32_t mergeId = mergeInst->GetSingleWordInOperand(0);
- BasicBlock* merge = context()->get_instr_block(mergeId);
- uint32_t mergeIndex = structured_order_index_[merge];
- get_def_use_mgr()->ForEachUser(
- mergeId, [headerIndex, mergeIndex, this](Instruction* user) {
- if (!user->IsBranch()) return;
- BasicBlock* block = context()->get_instr_block(user);
- uint32_t index = structured_order_index_[block];
- if (headerIndex < index && index < mergeIndex) {
- // This is a break from the loop.
- AddToWorklist(user);
- // Add branch's merge if there is one.
- Instruction* userMerge = branch2merge_[user];
- if (userMerge != nullptr) AddToWorklist(userMerge);
- }
- });
+ get_def_use_mgr()->ForEachUser(mergeId, [header, this](Instruction* user) {
+ if (!user->IsBranch()) return;
+ BasicBlock* block = context()->get_instr_block(user);
+ if (BlockIsInConstruct(header, block)) {
+ // This is a break from the loop.
+ AddToWorklist(user);
+ // Add branch's merge if there is one.
+ Instruction* userMerge = GetMergeInstruction(user);
+ if (userMerge != nullptr) AddToWorklist(userMerge);
+ }
+ });
if (mergeInst->opcode() != SpvOpLoopMerge) {
return;
@@ -292,7 +238,7 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
if (op == SpvOpBranchConditional || op == SpvOpSwitch) {
// A conditional branch or switch can only be a continue if it does not
// have a merge instruction or its merge block is not the continue block.
- Instruction* hdrMerge = branch2merge_[user];
+ Instruction* hdrMerge = GetMergeInstruction(user);
if (hdrMerge != nullptr && hdrMerge->opcode() == SpvOpSelectionMerge) {
uint32_t hdrMergeId =
hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx);
@@ -304,9 +250,9 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
// An unconditional branch can only be a continue if it is not
// branching to its own merge block.
BasicBlock* blk = context()->get_instr_block(user);
- Instruction* hdrBranch = block2headerBranch_[blk];
+ Instruction* hdrBranch = GetHeaderBranch(blk);
if (hdrBranch == nullptr) return;
- Instruction* hdrMerge = branch2merge_[hdrBranch];
+ Instruction* hdrMerge = GetMergeInstruction(hdrBranch);
if (hdrMerge->opcode() == SpvOpLoopMerge) return;
uint32_t hdrMergeId =
hdrMerge->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx);
@@ -321,113 +267,25 @@ void AggressiveDCEPass::AddBreaksAndContinuesToWorklist(
bool AggressiveDCEPass::AggressiveDCE(Function* func) {
// Mark function parameters as live.
AddToWorklist(&func->DefInst());
- func->ForEachParam(
- [this](const Instruction* param) {
- AddToWorklist(const_cast<Instruction*>(param));
- },
- false);
+ MarkFunctionParameterAsLive(func);
- // Compute map from block to controlling conditional branch
std::list<BasicBlock*> structuredOrder;
cfg()->ComputeStructuredOrder(func, &*func->begin(), &structuredOrder);
- ComputeBlock2HeaderMaps(structuredOrder);
bool modified = false;
- // Add instructions with external side effects to worklist. Also add branches
- // EXCEPT those immediately contained in an "if" selection construct or a loop
- // or continue construct.
- // TODO(greg-lunarg): Handle Frexp, Modf more optimally
- call_in_func_ = false;
- func_is_entry_point_ = false;
- private_stores_.clear();
live_local_vars_.clear();
- // Stacks to keep track of when we are inside an if- or loop-construct.
- // When immediately inside an if- or loop-construct, we do not initially
- // mark branches live. All other branches must be marked live.
- std::stack<bool> assume_branches_live;
- std::stack<uint32_t> currentMergeBlockId;
- // Push sentinel values on stack for when outside of any control flow.
- assume_branches_live.push(true);
- currentMergeBlockId.push(0);
- for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) {
- // If exiting if or loop, update stacks
- if ((*bi)->id() == currentMergeBlockId.top()) {
- assume_branches_live.pop();
- currentMergeBlockId.pop();
- }
- for (auto ii = (*bi)->begin(); ii != (*bi)->end(); ++ii) {
- SpvOp op = ii->opcode();
- switch (op) {
- case SpvOpStore: {
- uint32_t varId;
- (void)GetPtr(&*ii, &varId);
- // Mark stores as live if their variable is not function scope
- // and is not private scope. Remember private stores for possible
- // later inclusion. We cannot call IsLocalVar at this point because
- // private_like_local_ has not been set yet.
- if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
- IsVarOfStorage(varId, SpvStorageClassWorkgroup))
- private_stores_.push_back(&*ii);
- else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
- AddToWorklist(&*ii);
- } break;
- case SpvOpCopyMemory:
- case SpvOpCopyMemorySized: {
- uint32_t varId;
- (void)GetPtr(ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx),
- &varId);
- if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
- IsVarOfStorage(varId, SpvStorageClassWorkgroup))
- private_stores_.push_back(&*ii);
- else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
- AddToWorklist(&*ii);
- } break;
- case SpvOpLoopMerge: {
- assume_branches_live.push(false);
- currentMergeBlockId.push(
- ii->GetSingleWordInOperand(kLoopMergeMergeBlockIdInIdx));
- } break;
- case SpvOpSelectionMerge: {
- assume_branches_live.push(false);
- currentMergeBlockId.push(
- ii->GetSingleWordInOperand(kSelectionMergeMergeBlockIdInIdx));
- } break;
- case SpvOpSwitch:
- case SpvOpBranch:
- case SpvOpBranchConditional:
- case SpvOpUnreachable: {
- if (assume_branches_live.top()) {
- AddToWorklist(&*ii);
- }
- } break;
- default: {
- // Function calls, atomics, function params, function returns, etc.
- // TODO(greg-lunarg): function calls live only if write to non-local
- if (!ii->IsOpcodeSafeToDelete()) {
- AddToWorklist(&*ii);
- }
- // Remember function calls
- if (op == SpvOpFunctionCall) call_in_func_ = true;
- } break;
- }
- }
- }
- // See if current function is an entry point
- for (auto& ei : get_module()->entry_points()) {
- if (ei.GetSingleWordInOperand(kEntryPointFunctionIdInIdx) ==
- func->result_id()) {
- func_is_entry_point_ = true;
- break;
- }
- }
- // If the current function is an entry point and has no function calls,
- // we can optimize private variables as locals
- private_like_local_ = func_is_entry_point_ && !call_in_func_;
- // If privates are not like local, add their stores to worklist
- if (!private_like_local_)
- for (auto& ps : private_stores_) AddToWorklist(ps);
+ InitializeWorkList(func, structuredOrder);
+
// Perform closure on live instruction set.
while (!worklist_.empty()) {
Instruction* liveInst = worklist_.front();
+ // Add all operand instructions of Debug[No]Lines
+ for (auto& lineInst : liveInst->dbg_line_insts()) {
+ if (lineInst.IsDebugLineInst()) {
+ lineInst.ForEachInId([this](const uint32_t* iid) {
+ AddToWorklist(get_def_use_mgr()->GetDef(*iid));
+ });
+ }
+ }
// Add all operand instructions if not already live
liveInst->ForEachInId([&liveInst, this](const uint32_t* iid) {
Instruction* inInst = get_def_use_mgr()->GetDef(*iid);
@@ -440,21 +298,26 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) {
if (liveInst->type_id() != 0) {
AddToWorklist(get_def_use_mgr()->GetDef(liveInst->type_id()));
}
+ BasicBlock* basic_block = context()->get_instr_block(liveInst);
+ if (basic_block != nullptr) {
+ AddToWorklist(basic_block->GetLabelInst());
+ }
+
// If in a structured if or loop construct, add the controlling
// conditional branch and its merge.
BasicBlock* blk = context()->get_instr_block(liveInst);
- Instruction* branchInst = block2headerBranch_[blk];
+ Instruction* branchInst = GetHeaderBranch(blk);
if (branchInst != nullptr) {
AddToWorklist(branchInst);
- Instruction* mergeInst = branch2merge_[branchInst];
+ Instruction* mergeInst = GetMergeInstruction(branchInst);
AddToWorklist(mergeInst);
}
// If the block is a header, add the next outermost controlling
// conditional branch and its merge.
- Instruction* nextBranchInst = header2nextHeaderBranch_[blk];
+ Instruction* nextBranchInst = GetBranchForNextHeader(blk);
if (nextBranchInst != nullptr) {
AddToWorklist(nextBranchInst);
- Instruction* mergeInst = branch2merge_[nextBranchInst];
+ Instruction* mergeInst = GetMergeInstruction(nextBranchInst);
AddToWorklist(mergeInst);
}
// If local load, add all variable's stores if variable not already live
@@ -595,6 +458,89 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) {
return modified;
}
+void AggressiveDCEPass::InitializeWorkList(
+ Function* func, std::list<BasicBlock*>& structuredOrder) {
+ // Add instructions with external side effects to the worklist. Also add
+ // branches that are not attached to a structured construct.
+ // TODO(s-perron): The handling of branch seems to be adhoc. This needs to be
+ // cleaned up.
+ bool call_in_func = false;
+ bool func_is_entry_point = false;
+
+ // TODO(s-perron): We need to check if this is actually needed. In cases
+ // where private variable can be treated as if they are function scope, the
+ // private-to-local pass should be able to change them to function scope.
+ std::vector<Instruction*> private_stores;
+
+ for (auto bi = structuredOrder.begin(); bi != structuredOrder.end(); ++bi) {
+ for (auto ii = (*bi)->begin(); ii != (*bi)->end(); ++ii) {
+ SpvOp op = ii->opcode();
+ switch (op) {
+ case SpvOpStore: {
+ uint32_t varId;
+ (void)GetPtr(&*ii, &varId);
+ // Mark stores as live if their variable is not function scope
+ // and is not private scope. Remember private stores for possible
+ // later inclusion. We cannot call IsLocalVar at this point because
+ // private_like_local_ has not been set yet.
+ if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
+ IsVarOfStorage(varId, SpvStorageClassWorkgroup))
+ private_stores.push_back(&*ii);
+ else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
+ AddToWorklist(&*ii);
+ } break;
+ case SpvOpCopyMemory:
+ case SpvOpCopyMemorySized: {
+ uint32_t varId;
+ (void)GetPtr(ii->GetSingleWordInOperand(kCopyMemoryTargetAddrInIdx),
+ &varId);
+ if (IsVarOfStorage(varId, SpvStorageClassPrivate) ||
+ IsVarOfStorage(varId, SpvStorageClassWorkgroup))
+ private_stores.push_back(&*ii);
+ else if (!IsVarOfStorage(varId, SpvStorageClassFunction))
+ AddToWorklist(&*ii);
+ } break;
+ case SpvOpSwitch:
+ case SpvOpBranch:
+ case SpvOpBranchConditional:
+ case SpvOpUnreachable: {
+ bool branchRelatedToConstruct =
+ (GetMergeInstruction(&*ii) == nullptr &&
+ GetHeaderBlock(context()->get_instr_block(&*ii)) == nullptr);
+ if (branchRelatedToConstruct) {
+ AddToWorklist(&*ii);
+ }
+ } break;
+ case SpvOpLoopMerge:
+ case SpvOpSelectionMerge:
+ break;
+ default: {
+ // Function calls, atomics, function params, function returns, etc.
+ if (!ii->IsOpcodeSafeToDelete()) {
+ AddToWorklist(&*ii);
+ }
+ // Remember function calls
+ if (op == SpvOpFunctionCall) call_in_func = true;
+ } break;
+ }
+ }
+ }
+ // See if current function is an entry point
+ for (auto& ei : get_module()->entry_points()) {
+ if (ei.GetSingleWordInOperand(kEntryPointFunctionIdInIdx) ==
+ func->result_id()) {
+ func_is_entry_point = true;
+ break;
+ }
+ }
+ // If the current function is an entry point and has no function calls,
+ // we can optimize private variables as locals
+ private_like_local_ = func_is_entry_point && !call_in_func;
+ // If privates are not like local, add their stores to worklist
+ if (!private_like_local_)
+ for (auto& ps : private_stores) AddToWorklist(ps);
+}
+
void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() {
// Keep all execution modes.
for (auto& exec : get_module()->execution_modes()) {
@@ -602,7 +548,8 @@ void AggressiveDCEPass::InitializeModuleScopeLiveInstructions() {
}
// Keep all entry points.
for (auto& entry : get_module()->entry_points()) {
- if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
+ if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4) &&
+ !preserve_interface_) {
// In SPIR-V 1.4 and later, entry points must list all global variables
// used. DCE can still remove non-input/output variables and update the
// interface list. Mark the entry point as live and inputs and outputs as
@@ -690,7 +637,7 @@ Pass::Status AggressiveDCEPass::ProcessImpl() {
// Process all entry point functions.
ProcessFunction pfn = [this](Function* fp) { return AggressiveDCE(fp); };
- modified |= context()->ProcessEntryPointCallTree(pfn);
+ modified |= context()->ProcessReachableCallTree(pfn);
// If the decoration manager is kept live then the context will try to keep it
// up to date. ADCE deals with group decorations by changing the operands in
@@ -717,21 +664,20 @@ Pass::Status AggressiveDCEPass::ProcessImpl() {
// Cleanup all CFG including all unreachable blocks.
ProcessFunction cleanup = [this](Function* f) { return CFGCleanup(f); };
- modified |= context()->ProcessEntryPointCallTree(cleanup);
+ modified |= context()->ProcessReachableCallTree(cleanup);
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
bool AggressiveDCEPass::EliminateDeadFunctions() {
// Identify live functions first. Those that are not live
- // are dead. ADCE is disabled for non-shaders so we do not check for exported
- // functions here.
+ // are dead.
std::unordered_set<const Function*> live_function_set;
ProcessFunction mark_live = [&live_function_set](Function* fp) {
live_function_set.insert(fp);
return false;
};
- context()->ProcessEntryPointCallTree(mark_live);
+ context()->ProcessReachableCallTree(mark_live);
bool modified = false;
for (auto funcIter = get_module()->begin();
@@ -909,7 +855,8 @@ bool AggressiveDCEPass::ProcessGlobalValues() {
}
}
- if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
+ if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4) &&
+ !preserve_interface_) {
// Remove the dead interface variables from the entry point interface list.
for (auto& entry : get_module()->entry_points()) {
std::vector<Operand> new_operands;
@@ -935,8 +882,6 @@ bool AggressiveDCEPass::ProcessGlobalValues() {
return modified;
}
-AggressiveDCEPass::AggressiveDCEPass() = default;
-
Pass::Status AggressiveDCEPass::Process() {
// Initialize extensions allowlist
InitExtensions();
@@ -998,8 +943,80 @@ void AggressiveDCEPass::InitExtensions() {
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
"SPV_EXT_shader_image_int64",
+ "SPV_KHR_non_semantic_info",
});
}
+Instruction* AggressiveDCEPass::GetHeaderBranch(BasicBlock* blk) {
+ if (blk == nullptr) {
+ return nullptr;
+ }
+ BasicBlock* header_block = GetHeaderBlock(blk);
+ if (header_block == nullptr) {
+ return nullptr;
+ }
+ return header_block->terminator();
+}
+
+BasicBlock* AggressiveDCEPass::GetHeaderBlock(BasicBlock* blk) const {
+ if (blk == nullptr) {
+ return nullptr;
+ }
+
+ BasicBlock* header_block = nullptr;
+ if (blk->IsLoopHeader()) {
+ header_block = blk;
+ } else {
+ uint32_t header =
+ context()->GetStructuredCFGAnalysis()->ContainingConstruct(blk->id());
+ header_block = context()->get_instr_block(header);
+ }
+ return header_block;
+}
+
+Instruction* AggressiveDCEPass::GetMergeInstruction(Instruction* inst) {
+ BasicBlock* bb = context()->get_instr_block(inst);
+ if (bb == nullptr) {
+ return nullptr;
+ }
+ return bb->GetMergeInst();
+}
+
+Instruction* AggressiveDCEPass::GetBranchForNextHeader(BasicBlock* blk) {
+ if (blk == nullptr) {
+ return nullptr;
+ }
+
+ if (blk->IsLoopHeader()) {
+ uint32_t header =
+ context()->GetStructuredCFGAnalysis()->ContainingConstruct(blk->id());
+ blk = context()->get_instr_block(header);
+ }
+ return GetHeaderBranch(blk);
+}
+
+void AggressiveDCEPass::MarkFunctionParameterAsLive(const Function* func) {
+ func->ForEachParam(
+ [this](const Instruction* param) {
+ AddToWorklist(const_cast<Instruction*>(param));
+ },
+ false);
+}
+
+bool AggressiveDCEPass::BlockIsInConstruct(BasicBlock* header_block,
+ BasicBlock* bb) {
+ if (bb == nullptr || header_block == nullptr) {
+ return false;
+ }
+
+ uint32_t current_header = bb->id();
+ while (current_header != 0) {
+ if (current_header == header_block->id()) return true;
+ current_header = context()->GetStructuredCFGAnalysis()->ContainingConstruct(
+ current_header);
+ }
+ return false;
+}
+
} // namespace opt
} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h
index f02e729fd59..cd697b532e3 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/aggressive_dead_code_elim_pass.h
@@ -44,7 +44,9 @@ class AggressiveDCEPass : public MemPass {
using GetBlocksFunction =
std::function<std::vector<BasicBlock*>*(const BasicBlock*)>;
- AggressiveDCEPass();
+ AggressiveDCEPass(bool preserve_interface = false)
+ : preserve_interface_(preserve_interface) {}
+
const char* name() const override { return "eliminate-dead-code-aggressive"; }
Status Process() override;
@@ -55,6 +57,12 @@ class AggressiveDCEPass : public MemPass {
}
private:
+ // Preserve entry point interface if true. All variables in interface
+ // will be marked live and will not be eliminated. This mode is needed by
+ // GPU-Assisted Validation instrumentation where a change in the interface
+ // is not allowed.
+ bool preserve_interface_;
+
// Return true if |varId| is a variable of |storageClass|. |varId| must either
// be 0 or the result of an instruction.
bool IsVarOfStorage(uint32_t varId, uint32_t storageClass);
@@ -101,18 +109,6 @@ class AggressiveDCEPass : public MemPass {
// If |varId| is local, mark all stores of varId as live.
void ProcessLoad(Function* func, uint32_t varId);
- // If |bp| is structured header block, returns true and sets |mergeInst| to
- // the merge instruction, |branchInst| to the branch and |mergeBlockId| to the
- // merge block if they are not nullptr. Any of |mergeInst|, |branchInst| or
- // |mergeBlockId| may be a null pointer. Returns false if |bp| is a null
- // pointer.
- bool IsStructuredHeader(BasicBlock* bp, Instruction** mergeInst,
- Instruction** branchInst, uint32_t* mergeBlockId);
-
- // Initialize block2headerBranch_, header2nextHeaderBranch_, and
- // branch2merge_ using |structuredOrder| to order blocks.
- void ComputeBlock2HeaderMaps(std::list<BasicBlock*>& structuredOrder);
-
// Add branch to |labelId| to end of block |bp|.
void AddBranch(uint32_t labelId, BasicBlock* bp);
@@ -140,11 +136,33 @@ class AggressiveDCEPass : public MemPass {
Pass::Status ProcessImpl();
- // True if current function has a call instruction contained in it
- bool call_in_func_;
+ // Adds instructions which must be kept because of they have side-effects
+ // that ADCE cannot model to the work list.
+ void InitializeWorkList(Function* func,
+ std::list<BasicBlock*>& structuredOrder);
+
+ // Marks all of the OpFunctionParameter instructions in |func| as live.
+ void MarkFunctionParameterAsLive(const Function* func);
+
+ // Returns the terminator instruction in the header for the innermost
+ // construct that contains |blk|. Returns nullptr if no such header exists.
+ Instruction* GetHeaderBranch(BasicBlock* blk);
+
+ // Returns the header for the innermost construct that contains |blk|. A loop
+ // header will be its own header. Returns nullptr if no such header exists.
+ BasicBlock* GetHeaderBlock(BasicBlock* blk) const;
- // True if current function is an entry point
- bool func_is_entry_point_;
+ // Returns the same as |GetHeaderBlock| except if |blk| is a loop header it
+ // will return the header of the next enclosing construct. Returns nullptr if
+ // no such header exists.
+ Instruction* GetBranchForNextHeader(BasicBlock* blk);
+
+ // Returns the merge instruction in the same basic block as |inst|. Returns
+ // nullptr if one does not exist.
+ Instruction* GetMergeInstruction(Instruction* inst);
+
+ // Returns true if |bb| is in the construct with header |header_block|.
+ bool BlockIsInConstruct(BasicBlock* header_block, BasicBlock* bb);
// True if current function is entry point and has no function calls.
bool private_like_local_;
@@ -156,27 +174,6 @@ class AggressiveDCEPass : public MemPass {
// building up the live instructions set |live_insts_|.
std::queue<Instruction*> worklist_;
- // Map from block to the branch instruction in the header of the most
- // immediate controlling structured if or loop. A loop header block points
- // to its own branch instruction. An if-selection block points to the branch
- // of an enclosing construct's header, if one exists.
- std::unordered_map<BasicBlock*, Instruction*> block2headerBranch_;
-
- // Map from header block to the branch instruction in the header of the
- // structured construct enclosing it.
- // The liveness algorithm is designed to iteratively mark as live all
- // structured constructs enclosing a live instruction.
- std::unordered_map<BasicBlock*, Instruction*> header2nextHeaderBranch_;
-
- // Maps basic block to their index in the structured order traversal.
- std::unordered_map<BasicBlock*, uint32_t> structured_order_index_;
-
- // Map from branch to its associated merge instruction, if any
- std::unordered_map<Instruction*, Instruction*> branch2merge_;
-
- // Store instructions to variables of private storage
- std::vector<Instruction*> private_stores_;
-
// Live Instructions
utils::BitVector live_insts_;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/block_merge_util.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/block_merge_util.cpp
index 15e8c6ff9cb..e4ba10fc9f8 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/block_merge_util.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/block_merge_util.cpp
@@ -173,7 +173,9 @@ void MergeWithSuccessor(IRContext* context, Function* func,
auto& vec = terminator->dbg_line_insts();
auto& new_vec = merge_inst->dbg_line_insts();
new_vec.insert(new_vec.end(), vec.begin(), vec.end());
- terminator->clear_dbg_line_insts();
+ terminator->ClearDbgLineInsts();
+ for (auto& l_inst : new_vec)
+ context->get_def_use_mgr()->AnalyzeInstDefUse(&l_inst);
// Move the merge instruction to just before the terminator.
merge_inst->InsertBefore(terminator);
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/compact_ids_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/compact_ids_pass.cpp
index 67091531c5d..8815b8c6583 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/compact_ids_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/compact_ids_pass.cpp
@@ -86,9 +86,12 @@ Pass::Status CompactIdsPass::Process() {
},
true);
- if (modified)
+ if (modified) {
context()->module()->SetIdBound(
static_cast<uint32_t>(result_id_mapping.size() + 1));
+ // There are ids in the feature manager that could now be invalid
+ context()->ResetFeatureManager();
+ }
return modified ? Status::SuccessWithChange : Status::SuccessWithoutChange;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp
index d262a7ecab3..515a3ed5dfa 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/const_folding_rules.cpp
@@ -1002,7 +1002,7 @@ const analysis::Constant* FoldClamp1(
"Expecting a GLSLstd450 extended instruction.");
// Make sure all Clamp operands are constants.
- for (uint32_t i = 1; i < 3; i++) {
+ for (uint32_t i = 1; i < 4; i++) {
if (constants[i] == nullptr) {
return nullptr;
}
@@ -1017,7 +1017,7 @@ const analysis::Constant* FoldClamp1(
context);
}
-// Fold a clamp instruction when |x >= min_val|.
+// Fold a clamp instruction when |x <= min_val|.
const analysis::Constant* FoldClamp2(
IRContext* context, Instruction* inst,
const std::vector<const analysis::Constant*>& constants) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp
index 19ca6008dac..a3dac5d7757 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp
@@ -432,6 +432,12 @@ uint32_t ConstantManager::GetSIntConst(int32_t val) {
return GetDefiningInstruction(c)->result_id();
}
+uint32_t ConstantManager::GetUIntConst(uint32_t val) {
+ Type* uint_type = context()->get_type_mgr()->GetUIntType();
+ const Constant* c = GetConstant(uint_type, {val});
+ return GetDefiningInstruction(c)->result_id();
+}
+
std::vector<const analysis::Constant*> Constant::GetVectorComponents(
analysis::ConstantManager* const_mgr) const {
std::vector<const analysis::Constant*> components;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.h
index 7b41ae27b25..acc64cd2d16 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/constants.h
@@ -642,6 +642,9 @@ class ConstantManager {
// Returns the id of a 32-bit signed integer constant with value |val|.
uint32_t GetSIntConst(int32_t val);
+ // Returns the id of a 32-bit unsigned integer constant with value |val|.
+ uint32_t GetUIntConst(uint32_t val);
+
private:
// Creates a Constant instance with the given type and a vector of constant
// defining words. Returns a unique pointer to the created Constant instance
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp
new file mode 100644
index 00000000000..e84d3578a82
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp
@@ -0,0 +1,437 @@
+// Copyright (c) 2021 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 "source/opt/convert_to_sampled_image_pass.h"
+
+#include <cctype>
+#include <cstring>
+#include <tuple>
+
+#include "source/opt/ir_builder.h"
+#include "source/util/make_unique.h"
+#include "source/util/parse_number.h"
+
+namespace spvtools {
+namespace opt {
+
+using VectorOfDescriptorSetAndBindingPairs =
+ std::vector<DescriptorSetAndBinding>;
+using DescriptorSetBindingToInstruction =
+ ConvertToSampledImagePass::DescriptorSetBindingToInstruction;
+
+namespace {
+
+using utils::ParseNumber;
+
+// Returns true if the given char is ':', '\0' or considered as blank space
+// (i.e.: '\n', '\r', '\v', '\t', '\f' and ' ').
+bool IsSeparator(char ch) {
+ return std::strchr(":\0", ch) || std::isspace(ch) != 0;
+}
+
+// Reads characters starting from |str| until it meets a separator. Parses a
+// number from the characters and stores it into |number|. Returns the pointer
+// to the separator if it succeeds. Otherwise, returns nullptr.
+const char* ParseNumberUntilSeparator(const char* str, uint32_t* number) {
+ const char* number_begin = str;
+ while (!IsSeparator(*str)) str++;
+ const char* number_end = str;
+ std::string number_in_str(number_begin, number_end - number_begin);
+ if (!utils::ParseNumber(number_in_str.c_str(), number)) {
+ // The descriptor set is not a valid uint32 number.
+ return nullptr;
+ }
+ return str;
+}
+
+// Returns id of the image type used for the sampled image type of
+// |sampled_image|.
+uint32_t GetImageTypeOfSampledImage(analysis::TypeManager* type_mgr,
+ Instruction* sampled_image) {
+ auto* sampled_image_type =
+ type_mgr->GetType(sampled_image->type_id())->AsSampledImage();
+ return type_mgr->GetTypeInstruction(sampled_image_type->image_type());
+}
+
+// Finds the instruction whose id is |inst_id|. Follows the operand of
+// OpCopyObject recursively if the opcode of the instruction is OpCopyObject
+// and returns the first instruction that does not have OpCopyObject as opcode.
+Instruction* GetNonCopyObjectDef(analysis::DefUseManager* def_use_mgr,
+ uint32_t inst_id) {
+ Instruction* inst = def_use_mgr->GetDef(inst_id);
+ while (inst->opcode() == SpvOpCopyObject) {
+ inst_id = inst->GetSingleWordInOperand(0u);
+ inst = def_use_mgr->GetDef(inst_id);
+ }
+ return inst;
+}
+
+} // namespace
+
+bool ConvertToSampledImagePass::GetDescriptorSetBinding(
+ const Instruction& inst,
+ DescriptorSetAndBinding* descriptor_set_binding) const {
+ auto* decoration_manager = context()->get_decoration_mgr();
+ bool found_descriptor_set_to_convert = false;
+ bool found_binding_to_convert = false;
+ for (auto decorate :
+ decoration_manager->GetDecorationsFor(inst.result_id(), false)) {
+ uint32_t decoration = decorate->GetSingleWordInOperand(1u);
+ if (decoration == SpvDecorationDescriptorSet) {
+ if (found_descriptor_set_to_convert) {
+ assert(false && "A resource has two OpDecorate for the descriptor set");
+ return false;
+ }
+ descriptor_set_binding->descriptor_set =
+ decorate->GetSingleWordInOperand(2u);
+ found_descriptor_set_to_convert = true;
+ } else if (decoration == SpvDecorationBinding) {
+ if (found_binding_to_convert) {
+ assert(false && "A resource has two OpDecorate for the binding");
+ return false;
+ }
+ descriptor_set_binding->binding = decorate->GetSingleWordInOperand(2u);
+ found_binding_to_convert = true;
+ }
+ }
+ return found_descriptor_set_to_convert && found_binding_to_convert;
+}
+
+bool ConvertToSampledImagePass::ShouldResourceBeConverted(
+ const DescriptorSetAndBinding& descriptor_set_binding) const {
+ return descriptor_set_binding_pairs_.find(descriptor_set_binding) !=
+ descriptor_set_binding_pairs_.end();
+}
+
+const analysis::Type* ConvertToSampledImagePass::GetVariableType(
+ const Instruction& variable) const {
+ if (variable.opcode() != SpvOpVariable) return nullptr;
+ auto* type = context()->get_type_mgr()->GetType(variable.type_id());
+ auto* pointer_type = type->AsPointer();
+ if (!pointer_type) return nullptr;
+
+ return pointer_type->pointee_type();
+}
+
+SpvStorageClass ConvertToSampledImagePass::GetStorageClass(
+ const Instruction& variable) const {
+ assert(variable.opcode() == SpvOpVariable);
+ auto* type = context()->get_type_mgr()->GetType(variable.type_id());
+ auto* pointer_type = type->AsPointer();
+ if (!pointer_type) return SpvStorageClassMax;
+
+ return pointer_type->storage_class();
+}
+
+bool ConvertToSampledImagePass::CollectResourcesToConvert(
+ DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler,
+ DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image)
+ const {
+ for (auto& inst : context()->types_values()) {
+ const auto* variable_type = GetVariableType(inst);
+ if (variable_type == nullptr) continue;
+
+ DescriptorSetAndBinding descriptor_set_binding;
+ if (!GetDescriptorSetBinding(inst, &descriptor_set_binding)) continue;
+
+ if (!ShouldResourceBeConverted(descriptor_set_binding)) {
+ continue;
+ }
+
+ if (variable_type->AsImage()) {
+ if (!descriptor_set_binding_pair_to_image
+ ->insert({descriptor_set_binding, &inst})
+ .second) {
+ return false;
+ }
+ } else if (variable_type->AsSampler()) {
+ if (!descriptor_set_binding_pair_to_sampler
+ ->insert({descriptor_set_binding, &inst})
+ .second) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+Pass::Status ConvertToSampledImagePass::Process() {
+ Status status = Status::SuccessWithoutChange;
+
+ DescriptorSetBindingToInstruction descriptor_set_binding_pair_to_sampler,
+ descriptor_set_binding_pair_to_image;
+ if (!CollectResourcesToConvert(&descriptor_set_binding_pair_to_sampler,
+ &descriptor_set_binding_pair_to_image)) {
+ return Status::Failure;
+ }
+
+ for (auto& image : descriptor_set_binding_pair_to_image) {
+ status = CombineStatus(
+ status, UpdateImageVariableToSampledImage(image.second, image.first));
+ if (status == Status::Failure) {
+ return status;
+ }
+ }
+
+ for (const auto& sampler : descriptor_set_binding_pair_to_sampler) {
+ // Converting only a Sampler to Sampled Image is not allowed. It must have a
+ // corresponding image to combine the sampler with.
+ auto image_itr = descriptor_set_binding_pair_to_image.find(sampler.first);
+ if (image_itr == descriptor_set_binding_pair_to_image.end() ||
+ image_itr->second == nullptr) {
+ return Status::Failure;
+ }
+
+ status = CombineStatus(
+ status, CheckUsesOfSamplerVariable(sampler.second, image_itr->second));
+ if (status == Status::Failure) {
+ return status;
+ }
+ }
+
+ return status;
+}
+
+void ConvertToSampledImagePass::FindUses(const Instruction* inst,
+ std::vector<Instruction*>* uses,
+ uint32_t user_opcode) const {
+ auto* def_use_mgr = context()->get_def_use_mgr();
+ def_use_mgr->ForEachUser(inst, [uses, user_opcode, this](Instruction* user) {
+ if (user->opcode() == user_opcode) {
+ uses->push_back(user);
+ } else if (user->opcode() == SpvOpCopyObject) {
+ FindUses(user, uses, user_opcode);
+ }
+ });
+}
+
+void ConvertToSampledImagePass::FindUsesOfImage(
+ const Instruction* image, std::vector<Instruction*>* uses) const {
+ auto* def_use_mgr = context()->get_def_use_mgr();
+ def_use_mgr->ForEachUser(image, [uses, this](Instruction* user) {
+ switch (user->opcode()) {
+ case SpvOpImageFetch:
+ case SpvOpImageRead:
+ case SpvOpImageWrite:
+ case SpvOpImageQueryFormat:
+ case SpvOpImageQueryOrder:
+ case SpvOpImageQuerySizeLod:
+ case SpvOpImageQuerySize:
+ case SpvOpImageQueryLevels:
+ case SpvOpImageQuerySamples:
+ case SpvOpImageSparseFetch:
+ uses->push_back(user);
+ default:
+ break;
+ }
+ if (user->opcode() == SpvOpCopyObject) {
+ FindUsesOfImage(user, uses);
+ }
+ });
+}
+
+Instruction* ConvertToSampledImagePass::CreateImageExtraction(
+ Instruction* sampled_image) {
+ InstructionBuilder builder(
+ context(), sampled_image->NextNode(),
+ IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping);
+ return builder.AddUnaryOp(
+ GetImageTypeOfSampledImage(context()->get_type_mgr(), sampled_image),
+ SpvOpImage, sampled_image->result_id());
+}
+
+uint32_t ConvertToSampledImagePass::GetSampledImageTypeForImage(
+ Instruction* image_variable) {
+ const auto* variable_type = GetVariableType(*image_variable);
+ if (variable_type == nullptr) return 0;
+ const auto* image_type = variable_type->AsImage();
+ if (image_type == nullptr) return 0;
+
+ analysis::Image image_type_for_sampled_image(*image_type);
+ analysis::SampledImage sampled_image_type(&image_type_for_sampled_image);
+ return context()->get_type_mgr()->GetTypeInstruction(&sampled_image_type);
+}
+
+Instruction* ConvertToSampledImagePass::UpdateImageUses(
+ Instruction* sampled_image_load) {
+ std::vector<Instruction*> uses_of_load;
+ FindUsesOfImage(sampled_image_load, &uses_of_load);
+ if (uses_of_load.empty()) return nullptr;
+
+ auto* extracted_image = CreateImageExtraction(sampled_image_load);
+ for (auto* user : uses_of_load) {
+ user->SetInOperand(0, {extracted_image->result_id()});
+ context()->get_def_use_mgr()->AnalyzeInstUse(user);
+ }
+ return extracted_image;
+}
+
+bool ConvertToSampledImagePass::
+ IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
+ Instruction* sampled_image_inst,
+ const DescriptorSetAndBinding& descriptor_set_binding) {
+ auto* def_use_mgr = context()->get_def_use_mgr();
+ uint32_t sampler_id = sampled_image_inst->GetSingleWordInOperand(1u);
+ auto* sampler_load = def_use_mgr->GetDef(sampler_id);
+ if (sampler_load->opcode() != SpvOpLoad) return false;
+ auto* sampler = def_use_mgr->GetDef(sampler_load->GetSingleWordInOperand(0u));
+ DescriptorSetAndBinding sampler_descriptor_set_binding;
+ return GetDescriptorSetBinding(*sampler, &sampler_descriptor_set_binding) &&
+ sampler_descriptor_set_binding == descriptor_set_binding;
+}
+
+void ConvertToSampledImagePass::UpdateSampledImageUses(
+ Instruction* image_load, Instruction* image_extraction,
+ const DescriptorSetAndBinding& image_descriptor_set_binding) {
+ std::vector<Instruction*> sampled_image_users;
+ FindUses(image_load, &sampled_image_users, SpvOpSampledImage);
+
+ auto* def_use_mgr = context()->get_def_use_mgr();
+ for (auto* sampled_image_inst : sampled_image_users) {
+ if (IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
+ sampled_image_inst, image_descriptor_set_binding)) {
+ context()->ReplaceAllUsesWith(sampled_image_inst->result_id(),
+ image_load->result_id());
+ def_use_mgr->AnalyzeInstUse(image_load);
+ context()->KillInst(sampled_image_inst);
+ } else {
+ if (!image_extraction)
+ image_extraction = CreateImageExtraction(image_load);
+ sampled_image_inst->SetInOperand(0, {image_extraction->result_id()});
+ def_use_mgr->AnalyzeInstUse(sampled_image_inst);
+ }
+ }
+}
+
+void ConvertToSampledImagePass::MoveInstructionNextToType(Instruction* inst,
+ uint32_t type_id) {
+ auto* type_inst = context()->get_def_use_mgr()->GetDef(type_id);
+ inst->SetResultType(type_id);
+ inst->RemoveFromList();
+ inst->InsertAfter(type_inst);
+}
+
+bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage(
+ Instruction* image_variable, uint32_t sampled_image_type_id) {
+ auto* sampled_image_type =
+ context()->get_type_mgr()->GetType(sampled_image_type_id);
+ if (sampled_image_type == nullptr) return false;
+ auto storage_class = GetStorageClass(*image_variable);
+ if (storage_class == SpvStorageClassMax) return false;
+ analysis::Pointer sampled_image_pointer(sampled_image_type, storage_class);
+
+ // Make sure |image_variable| is behind its type i.e., avoid the forward
+ // reference.
+ uint32_t type_id =
+ context()->get_type_mgr()->GetTypeInstruction(&sampled_image_pointer);
+ MoveInstructionNextToType(image_variable, type_id);
+ return true;
+}
+
+Pass::Status ConvertToSampledImagePass::UpdateImageVariableToSampledImage(
+ Instruction* image_variable,
+ const DescriptorSetAndBinding& descriptor_set_binding) {
+ std::vector<Instruction*> image_variable_loads;
+ FindUses(image_variable, &image_variable_loads, SpvOpLoad);
+ if (image_variable_loads.empty()) return Status::SuccessWithoutChange;
+
+ const uint32_t sampled_image_type_id =
+ GetSampledImageTypeForImage(image_variable);
+ if (!sampled_image_type_id) return Status::Failure;
+
+ for (auto* load : image_variable_loads) {
+ load->SetResultType(sampled_image_type_id);
+ auto* image_extraction = UpdateImageUses(load);
+ UpdateSampledImageUses(load, image_extraction, descriptor_set_binding);
+ }
+
+ return ConvertImageVariableToSampledImage(image_variable,
+ sampled_image_type_id)
+ ? Status::SuccessWithChange
+ : Status::Failure;
+}
+
+bool ConvertToSampledImagePass::DoesSampledImageReferenceImage(
+ Instruction* sampled_image_inst, Instruction* image_variable) {
+ if (sampled_image_inst->opcode() != SpvOpSampledImage) return false;
+ auto* def_use_mgr = context()->get_def_use_mgr();
+ auto* image_load = GetNonCopyObjectDef(
+ def_use_mgr, sampled_image_inst->GetSingleWordInOperand(0u));
+ if (image_load->opcode() != SpvOpLoad) return false;
+ auto* image =
+ GetNonCopyObjectDef(def_use_mgr, image_load->GetSingleWordInOperand(0u));
+ return image->opcode() == SpvOpVariable &&
+ image->result_id() == image_variable->result_id();
+}
+
+Pass::Status ConvertToSampledImagePass::CheckUsesOfSamplerVariable(
+ const Instruction* sampler_variable,
+ Instruction* image_to_be_combined_with) {
+ if (image_to_be_combined_with == nullptr) return Status::Failure;
+
+ std::vector<Instruction*> sampler_variable_loads;
+ FindUses(sampler_variable, &sampler_variable_loads, SpvOpLoad);
+ for (auto* load : sampler_variable_loads) {
+ std::vector<Instruction*> sampled_image_users;
+ FindUses(load, &sampled_image_users, SpvOpSampledImage);
+ for (auto* sampled_image_inst : sampled_image_users) {
+ if (!DoesSampledImageReferenceImage(sampled_image_inst,
+ image_to_be_combined_with)) {
+ return Status::Failure;
+ }
+ }
+ }
+ return Status::SuccessWithoutChange;
+}
+
+std::unique_ptr<VectorOfDescriptorSetAndBindingPairs>
+ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString(
+ const char* str) {
+ if (!str) return nullptr;
+
+ auto descriptor_set_binding_pairs =
+ MakeUnique<VectorOfDescriptorSetAndBindingPairs>();
+
+ while (std::isspace(*str)) str++; // skip leading spaces.
+
+ // The parsing loop, break when points to the end.
+ while (*str) {
+ // Parse the descriptor set.
+ uint32_t descriptor_set = 0;
+ str = ParseNumberUntilSeparator(str, &descriptor_set);
+ if (str == nullptr) return nullptr;
+
+ // Find the ':', spaces between the descriptor set and the ':' are not
+ // allowed.
+ if (*str++ != ':') {
+ // ':' not found
+ return nullptr;
+ }
+
+ // Parse the binding.
+ uint32_t binding = 0;
+ str = ParseNumberUntilSeparator(str, &binding);
+ if (str == nullptr) return nullptr;
+
+ descriptor_set_binding_pairs->push_back({descriptor_set, binding});
+
+ // Skip trailing spaces.
+ while (std::isspace(*str)) str++;
+ }
+
+ return descriptor_set_binding_pairs;
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h
new file mode 100644
index 00000000000..d3938af7dc4
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h
@@ -0,0 +1,207 @@
+// Copyright (c) 2021 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 SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_
+#define SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_
+
+#include <memory>
+#include <unordered_set>
+#include <utility>
+
+#include "source/opt/pass.h"
+#include "source/opt/types.h"
+
+namespace spvtools {
+namespace opt {
+
+// A struct for a pair of descriptor set and binding.
+struct DescriptorSetAndBinding {
+ uint32_t descriptor_set;
+ uint32_t binding;
+
+ bool operator==(const DescriptorSetAndBinding& descriptor_set_binding) const {
+ return descriptor_set_binding.descriptor_set == descriptor_set &&
+ descriptor_set_binding.binding == binding;
+ }
+};
+
+// See optimizer.hpp for documentation.
+class ConvertToSampledImagePass : public Pass {
+ public:
+ // Hashing functor for the pair of descriptor set and binding.
+ struct DescriptorSetAndBindingHash {
+ size_t operator()(
+ const DescriptorSetAndBinding& descriptor_set_binding) const {
+ return std::hash<uint32_t>()(descriptor_set_binding.descriptor_set) ^
+ std::hash<uint32_t>()(descriptor_set_binding.binding);
+ }
+ };
+
+ using SetOfDescriptorSetAndBindingPairs =
+ std::unordered_set<DescriptorSetAndBinding, DescriptorSetAndBindingHash>;
+ using DescriptorSetBindingToInstruction =
+ std::unordered_map<DescriptorSetAndBinding, Instruction*,
+ DescriptorSetAndBindingHash>;
+
+ explicit ConvertToSampledImagePass(
+ const std::vector<DescriptorSetAndBinding>& descriptor_set_binding_pairs)
+ : descriptor_set_binding_pairs_(descriptor_set_binding_pairs.begin(),
+ descriptor_set_binding_pairs.end()) {}
+
+ const char* name() const override { return "convert-to-sampled-image"; }
+ Status Process() override;
+
+ // Parses the given null-terminated C string to get a vector of descriptor set
+ // and binding pairs. Returns a unique pointer to the vector of descriptor set
+ // and binding pairs built from the given |str| on success. Returns a nullptr
+ // if the given string is not valid for building the vector of pairs.
+ // A valid string for building the vector of pairs should follow the rule
+ // below:
+ //
+ // "<descriptor set>:<binding> <descriptor set>:<binding> ..."
+ // Example:
+ // "3:5 2:1 0:4"
+ //
+ // Entries are separated with blank spaces (i.e.:' ', '\n', '\r', '\t',
+ // '\f', '\v'). Each entry corresponds to a descriptor set and binding pair.
+ // Multiple spaces between, before or after entries are allowed. However,
+ // spaces are not allowed within a descriptor set or binding.
+ //
+ // In each entry, the descriptor set and binding are separated by ':'.
+ // Missing ':' in any entry is invalid. And it is invalid to have blank
+ // spaces in between the descriptor set and ':' or ':' and the binding.
+ //
+ // <descriptor set>: the descriptor set.
+ // The text must represent a valid uint32_t number.
+ //
+ // <binding>: the binding.
+ // The text must represent a valid uint32_t number.
+ static std::unique_ptr<std::vector<DescriptorSetAndBinding>>
+ ParseDescriptorSetBindingPairsString(const char* str);
+
+ private:
+ // Collects resources to convert to sampled image and saves them in
+ // |descriptor_set_binding_pair_to_sampler| if the resource is a sampler and
+ // saves them in |descriptor_set_binding_pair_to_image| if the resource is an
+ // image. Returns false if two samplers or two images have the same descriptor
+ // set and binding. Otherwise, returns true.
+ bool CollectResourcesToConvert(
+ DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_sampler,
+ DescriptorSetBindingToInstruction* descriptor_set_binding_pair_to_image)
+ const;
+
+ // Finds an OpDecorate with DescriptorSet decorating |inst| and another
+ // OpDecorate with Binding decorating |inst|. Stores the descriptor set and
+ // binding in |descriptor_set_binding|. Returns whether it successfully finds
+ // the descriptor set and binding or not.
+ bool GetDescriptorSetBinding(
+ const Instruction& inst,
+ DescriptorSetAndBinding* descriptor_set_binding) const;
+
+ // Returns whether |descriptor_set_binding| is a pair of a descriptor set
+ // and a binding that we have to convert resources with it to a sampled image
+ // or not.
+ bool ShouldResourceBeConverted(
+ const DescriptorSetAndBinding& descriptor_set_binding) const;
+
+ // Returns the pointee type of the type of variable |variable|. If |variable|
+ // is not an OpVariable instruction, just returns nullptr.
+ const analysis::Type* GetVariableType(const Instruction& variable) const;
+
+ // Returns the storage class of |variable|.
+ SpvStorageClass GetStorageClass(const Instruction& variable) const;
+
+ // Finds |inst|'s users whose opcode is |user_opcode| or users of OpCopyObject
+ // instructions of |inst| whose opcode is |user_opcode| and puts them in
+ // |uses|.
+ void FindUses(const Instruction* inst, std::vector<Instruction*>* uses,
+ uint32_t user_opcode) const;
+
+ // Finds OpImage* instructions using |image| or OpCopyObject instructions that
+ // copy |image| and puts them in |uses|.
+ void FindUsesOfImage(const Instruction* image,
+ std::vector<Instruction*>* uses) const;
+
+ // Creates an OpImage instruction that extracts the image from the sampled
+ // image |sampled_image|.
+ Instruction* CreateImageExtraction(Instruction* sampled_image);
+
+ // Converts |image_variable| whose type is an image pointer to sampled image
+ // type. Updates users of |image_variable| accordingly. If some instructions
+ // e.g., OpImageRead use |image_variable| as an Image operand, creates an
+ // image extracted from the sampled image using OpImage and replace the Image
+ // operands of the users with the extracted image. If some OpSampledImage
+ // instructions use |image_variable| and sampler whose descriptor set and
+ // binding are the same with |image_variable|, just combines |image_variable|
+ // and the sampler to a sampled image.
+ Pass::Status UpdateImageVariableToSampledImage(
+ Instruction* image_variable,
+ const DescriptorSetAndBinding& descriptor_set_binding);
+
+ // Returns the id of type sampled image type whose image type is the one of
+ // |image_variable|.
+ uint32_t GetSampledImageTypeForImage(Instruction* image_variable);
+
+ // Moves |inst| next to the OpType* instruction with |type_id|.
+ void MoveInstructionNextToType(Instruction* inst, uint32_t type_id);
+
+ // Converts |image_variable| whose type is an image pointer to sampled image
+ // with the type id |sampled_image_type_id|. Returns whether it successfully
+ // converts the type of |image_variable| or not.
+ bool ConvertImageVariableToSampledImage(Instruction* image_variable,
+ uint32_t sampled_image_type_id);
+
+ // Replaces |sampled_image_load| instruction used by OpImage* with the image
+ // extracted from |sampled_image_load|. Returns the extracted image or nullptr
+ // if it does not have uses.
+ Instruction* UpdateImageUses(Instruction* sampled_image_load);
+
+ // Returns true if the sampler of |sampled_image_inst| is decorated by a
+ // descriptor set and a binding |descriptor_set_binding|.
+ bool IsSamplerOfSampledImageDecoratedByDescriptorSetBinding(
+ Instruction* sampled_image_inst,
+ const DescriptorSetAndBinding& descriptor_set_binding);
+
+ // Replaces OpSampledImage instructions using |image_load| with |image_load|
+ // if the sampler of the OpSampledImage instruction has descriptor set and
+ // binding |image_descriptor_set_binding|. Otherwise, replaces |image_load|
+ // with |image_extraction|.
+ void UpdateSampledImageUses(
+ Instruction* image_load, Instruction* image_extraction,
+ const DescriptorSetAndBinding& image_descriptor_set_binding);
+
+ // Checks the uses of |sampler_variable|. When a sampler is used by
+ // OpSampledImage instruction, the corresponding image must be
+ // |image_to_be_combined_with| that should be already converted to a sampled
+ // image by UpdateImageVariableToSampledImage() method.
+ Pass::Status CheckUsesOfSamplerVariable(
+ const Instruction* sampler_variable,
+ Instruction* image_to_be_combined_with);
+
+ // Returns true if Image operand of |sampled_image_inst| is the image of
+ // |image_variable|.
+ bool DoesSampledImageReferenceImage(Instruction* sampled_image_inst,
+ Instruction* image_variable);
+
+ // A set of pairs of descriptor set and binding. If an image and/or a sampler
+ // have a pair of descriptor set and binding that is an element of
+ // |descriptor_set_binding_pairs_|, they/it will be converted to a sampled
+ // image by this pass.
+ const SetOfDescriptorSetAndBindingPairs descriptor_set_binding_pairs_;
+};
+
+} // namespace opt
+} // namespace spvtools
+
+#endif // SOURCE_OPT_CONVERT_TO_SAMPLED_IMAGE_PASS_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.cpp
new file mode 100644
index 00000000000..c91fad08e7e
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.cpp
@@ -0,0 +1,91 @@
+// Copyright (c) 2021 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 "source/opt/dataflow.h"
+
+#include <algorithm>
+#include <cstdint>
+
+namespace spvtools {
+namespace opt {
+
+bool DataFlowAnalysis::Enqueue(Instruction* inst) {
+ bool& is_enqueued = on_worklist_[inst];
+ if (is_enqueued) return false;
+ is_enqueued = true;
+ worklist_.push(inst);
+ return true;
+}
+
+DataFlowAnalysis::VisitResult DataFlowAnalysis::RunOnce(
+ Function* function, bool is_first_iteration) {
+ InitializeWorklist(function, is_first_iteration);
+ VisitResult ret = VisitResult::kResultFixed;
+ while (!worklist_.empty()) {
+ Instruction* top = worklist_.front();
+ worklist_.pop();
+ on_worklist_[top] = false;
+ VisitResult result = Visit(top);
+ if (result == VisitResult::kResultChanged) {
+ EnqueueSuccessors(top);
+ ret = VisitResult::kResultChanged;
+ }
+ }
+ return ret;
+}
+
+void DataFlowAnalysis::Run(Function* function) {
+ VisitResult result = RunOnce(function, true);
+ while (result == VisitResult::kResultChanged) {
+ result = RunOnce(function, false);
+ }
+}
+
+void ForwardDataFlowAnalysis::InitializeWorklist(Function* function,
+ bool /*is_first_iteration*/) {
+ context().cfg()->ForEachBlockInReversePostOrder(
+ function->entry().get(), [this](BasicBlock* bb) {
+ if (label_position_ == LabelPosition::kLabelsOnly) {
+ Enqueue(bb->GetLabelInst());
+ return;
+ }
+ if (label_position_ == LabelPosition::kLabelsAtBeginning) {
+ Enqueue(bb->GetLabelInst());
+ }
+ for (Instruction& inst : *bb) {
+ Enqueue(&inst);
+ }
+ if (label_position_ == LabelPosition::kLabelsAtEnd) {
+ Enqueue(bb->GetLabelInst());
+ }
+ });
+}
+
+void ForwardDataFlowAnalysis::EnqueueUsers(Instruction* inst) {
+ context().get_def_use_mgr()->ForEachUser(
+ inst, [this](Instruction* user) { Enqueue(user); });
+}
+
+void ForwardDataFlowAnalysis::EnqueueBlockSuccessors(Instruction* inst) {
+ if (inst->opcode() != SpvOpLabel) return;
+ context()
+ .cfg()
+ ->block(inst->result_id())
+ ->ForEachSuccessorLabel([this](uint32_t* label) {
+ Enqueue(context().cfg()->block(*label)->GetLabelInst());
+ });
+}
+
+} // namespace opt
+} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.h
new file mode 100644
index 00000000000..be07415db53
--- /dev/null
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.h
@@ -0,0 +1,148 @@
+// Copyright (c) 2021 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 SOURCE_OPT_DATAFLOW_H_
+#define SOURCE_OPT_DATAFLOW_H_
+
+#include <queue>
+#include <unordered_map>
+#include <vector>
+
+#include "source/opt/instruction.h"
+#include "source/opt/ir_context.h"
+
+namespace spvtools {
+namespace opt {
+
+// Generic data-flow analysis.
+// Maintains a worklist of instructions to process and processes them in a
+// specified order. See also ForwardDataFlowAnalysis, which is specialized for
+// forward data-flow analysis.
+class DataFlowAnalysis {
+ public:
+ // The result of a |Visit| operation on an instruction.
+ // This is used to determine when analysis has reached a fixpoint.
+ enum class VisitResult {
+ // The analysis result for this instruction has changed.
+ // This means that any instructions that depend on it (its successors) must
+ // be recomputed.
+ kResultChanged,
+ // The analysis result for this instruction has not changed.
+ // When all visit operations return |kResultFixed|, the analysis has reached
+ // a fixpoint (converged).
+ kResultFixed,
+ };
+
+ virtual ~DataFlowAnalysis() {}
+
+ // Run this analysis on a given function.
+ // For analyses which work interprocedurally, |function| may be ignored.
+ void Run(Function* function);
+
+ protected:
+ DataFlowAnalysis(IRContext& context) : context_(context) {}
+
+ // Initialize the worklist for a given function.
+ // |is_first_iteration| is true on the first call to |Run| and false
+ // afterwards. All subsequent runs are only necessary to check if the analysis
+ // has converged; if |EnqueueSuccessors| is complete, |InitializeWorklist|
+ // should do nothing after the first iteration.
+ virtual void InitializeWorklist(Function* function,
+ bool is_first_iteration) = 0;
+
+ // Enqueues the successors (instructions which use the analysis result) of
+ // |inst|. This is not required to be complete, but convergence is faster when
+ // it is. This is called whenever |Visit| returns |kResultChanged|.
+ virtual void EnqueueSuccessors(Instruction* inst) = 0;
+
+ // Visits the given instruction, recomputing the analysis result. This is
+ // called once per instruction queued in |InitializeWorklist| and afterward
+ // when a predecessor is changed, through |EnqueueSuccessors|.
+ virtual VisitResult Visit(Instruction* inst) = 0;
+
+ // Enqueues the given instruction to be visited. Ignored if already in the
+ // worklist.
+ bool Enqueue(Instruction* inst);
+
+ IRContext& context() { return context_; }
+
+ private:
+ // Runs one pass, calling |InitializeWorklist| and then iterating through the
+ // worklist until all fixed.
+ VisitResult RunOnce(Function* function, bool is_first_iteration);
+
+ IRContext& context_;
+ std::unordered_map<Instruction*, bool> on_worklist_;
+ // The worklist, which contains the list of instructions to be visited.
+ //
+ // The choice of data structure was influenced by the data in "Iterative
+ // Data-flow Analysis, Revisited" (Cooper et al, 2002).
+ // https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.125.1549&rep=rep1&type=pdf
+ // The paper shows that the overall performance benefit of a priority queue
+ // over a regular queue or stack is relatively small (or negative).
+ //
+ // A queue has the advantage that nodes are visited in the same order they are
+ // enqueued, which relieves the analysis from inserting nodes "backwards", for
+ // example in worklist initialization. Also, as the paper claims that sorting
+ // successors does not improve runtime, we can use a single queue which is
+ // modified during iteration.
+ std::queue<Instruction*> worklist_;
+};
+
+// A generic data flow analysis, specialized for forward analysis.
+class ForwardDataFlowAnalysis : public DataFlowAnalysis {
+ public:
+ // Indicates where labels should be in the worklist RPO ordering.
+ enum class LabelPosition {
+ // Labels should be placed at the beginning of their blocks.
+ kLabelsAtBeginning,
+ // Labels should be placed at the end of their blocks.
+ kLabelsAtEnd,
+ // Labels should not be in the worklist.
+ kNoLabels,
+ // Only labels should be placed in the worklist.
+ kLabelsOnly,
+ };
+
+ ForwardDataFlowAnalysis(IRContext& context, LabelPosition label_position)
+ : DataFlowAnalysis(context), label_position_(label_position) {}
+
+ protected:
+ // Initializes the worklist in reverse postorder, regardless of
+ // |is_first_iteration|. Labels are placed according to the label position
+ // specified in the constructor.
+ void InitializeWorklist(Function* function, bool is_first_iteration) override;
+
+ // Enqueues the users and block successors of the given instruction.
+ // See |EnqueueUsers| and |EnqueueBlockSuccessors|.
+ void EnqueueSuccessors(Instruction* inst) override {
+ EnqueueUsers(inst);
+ EnqueueBlockSuccessors(inst);
+ }
+
+ // Enqueues the users of the given instruction.
+ void EnqueueUsers(Instruction* inst);
+
+ // Enqueues the labels of the successors of the block corresponding to the
+ // given label instruction. Does nothing for other instructions.
+ void EnqueueBlockSuccessors(Instruction* inst);
+
+ private:
+ LabelPosition label_position_;
+};
+
+} // namespace opt
+} // namespace spvtools
+
+#endif // SOURCE_OPT_DATAFLOW_H_
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp
index e782641f229..6593c3fbded 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.cpp
@@ -18,12 +18,15 @@
#include "source/opt/ir_context.h"
-// Constants for OpenCL.DebugInfo.100 extension instructions.
+// Constants for OpenCL.DebugInfo.100 & NonSemantic.Shader.DebugInfo.100
+// extension instructions.
static const uint32_t kOpLineOperandLineIndex = 1;
static const uint32_t kLineOperandIndexDebugFunction = 7;
static const uint32_t kLineOperandIndexDebugLexicalBlock = 5;
static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
+static const uint32_t kDebugFunctionDefinitionOperandDebugFunctionIndex = 4;
+static const uint32_t kDebugFunctionDefinitionOperandOpFunctionIndex = 5;
static const uint32_t kDebugFunctionOperandParentIndex = 9;
static const uint32_t kDebugTypeCompositeOperandParentIndex = 9;
static const uint32_t kDebugLexicalBlockOperandParentIndex = 7;
@@ -46,8 +49,8 @@ namespace {
void SetInlinedOperand(Instruction* dbg_inlined_at, uint32_t inlined_operand) {
assert(dbg_inlined_at);
- assert(dbg_inlined_at->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugInlinedAt);
+ assert(dbg_inlined_at->GetCommonDebugOpcode() ==
+ CommonDebugInfoDebugInlinedAt);
if (dbg_inlined_at->NumOperands() <= kDebugInlinedAtOperandInlinedIndex) {
dbg_inlined_at->AddOperand(
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {inlined_operand}});
@@ -59,8 +62,8 @@ void SetInlinedOperand(Instruction* dbg_inlined_at, uint32_t inlined_operand) {
uint32_t GetInlinedOperand(Instruction* dbg_inlined_at) {
assert(dbg_inlined_at);
- assert(dbg_inlined_at->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugInlinedAt);
+ assert(dbg_inlined_at->GetCommonDebugOpcode() ==
+ CommonDebugInfoDebugInlinedAt);
if (dbg_inlined_at->NumOperands() <= kDebugInlinedAtOperandInlinedIndex)
return kNoInlinedAt;
return dbg_inlined_at->GetSingleWordOperand(
@@ -68,8 +71,7 @@ uint32_t GetInlinedOperand(Instruction* dbg_inlined_at) {
}
bool IsEmptyDebugExpression(Instruction* instr) {
- return instr->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugExpression &&
+ return (instr->GetCommonDebugOpcode() == CommonDebugInfoDebugExpression) &&
instr->NumOperands() == kDebugExpressOperandOperationIndex;
}
@@ -79,43 +81,63 @@ DebugInfoManager::DebugInfoManager(IRContext* c) : context_(c) {
AnalyzeDebugInsts(*c->module());
}
+uint32_t DebugInfoManager::GetDbgSetImportId() {
+ uint32_t setId =
+ context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo();
+ if (setId == 0) {
+ setId =
+ context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo();
+ }
+ return setId;
+}
+
Instruction* DebugInfoManager::GetDbgInst(uint32_t id) {
auto dbg_inst_it = id_to_dbg_inst_.find(id);
return dbg_inst_it == id_to_dbg_inst_.end() ? nullptr : dbg_inst_it->second;
}
void DebugInfoManager::RegisterDbgInst(Instruction* inst) {
- assert(
- inst->NumInOperands() != 0 &&
- context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo() ==
- inst->GetInOperand(0).words[0] &&
- "Given instruction is not a debug instruction");
+ assert(inst->NumInOperands() != 0 &&
+ (GetDbgSetImportId() == inst->GetInOperand(0).words[0]) &&
+ "Given instruction is not a debug instruction");
id_to_dbg_inst_[inst->result_id()] = inst;
}
void DebugInfoManager::RegisterDbgFunction(Instruction* inst) {
- assert(inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction &&
- "inst is not a DebugFunction");
- auto fn_id = inst->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex);
- // Do not register function that has been optimized away
- auto fn_inst = GetDbgInst(fn_id);
- if (fn_inst != nullptr) {
- assert(GetDbgInst(fn_id)->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugInfoNone);
- return;
+ if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction) {
+ auto fn_id = inst->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex);
+ // Do not register function that has been optimized away.
+ auto fn_inst = GetDbgInst(fn_id);
+ if (fn_inst != nullptr) {
+ assert(GetDbgInst(fn_id)->GetOpenCL100DebugOpcode() ==
+ OpenCLDebugInfo100DebugInfoNone);
+ return;
+ }
+ assert(
+ fn_id_to_dbg_fn_.find(fn_id) == fn_id_to_dbg_fn_.end() &&
+ "Register DebugFunction for a function that already has DebugFunction");
+ fn_id_to_dbg_fn_[fn_id] = inst;
+ } else if (inst->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
+ auto fn_id = inst->GetSingleWordOperand(
+ kDebugFunctionDefinitionOperandOpFunctionIndex);
+ auto fn_inst = GetDbgInst(inst->GetSingleWordOperand(
+ kDebugFunctionDefinitionOperandDebugFunctionIndex));
+ assert(fn_inst && fn_inst->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunction);
+ assert(fn_id_to_dbg_fn_.find(fn_id) == fn_id_to_dbg_fn_.end() &&
+ "Register DebugFunctionDefinition for a function that already has "
+ "DebugFunctionDefinition");
+ fn_id_to_dbg_fn_[fn_id] = fn_inst;
+ } else {
+ assert(false && "inst is not a DebugFunction");
}
- assert(
- fn_id_to_dbg_fn_.find(fn_id) == fn_id_to_dbg_fn_.end() &&
- "Register DebugFunction for a function that already has DebugFunction");
- fn_id_to_dbg_fn_[fn_id] = inst;
}
void DebugInfoManager::RegisterDbgDeclare(uint32_t var_id,
Instruction* dbg_declare) {
- assert(dbg_declare->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugDeclare ||
- dbg_declare->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugValue);
+ assert(dbg_declare->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare ||
+ dbg_declare->GetCommonDebugOpcode() == CommonDebugInfoDebugValue);
auto dbg_decl_itr = var_id_to_dbg_decl_.find(var_id);
if (dbg_decl_itr == var_id_to_dbg_decl_.end()) {
var_id_to_dbg_decl_[var_id] = {dbg_declare};
@@ -126,27 +148,36 @@ void DebugInfoManager::RegisterDbgDeclare(uint32_t var_id,
uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line,
const DebugScope& scope) {
- if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo() ==
- 0)
- return kNoInlinedAt;
+ uint32_t setId = GetDbgSetImportId();
+
+ if (setId == 0) return kNoInlinedAt;
+
+ spv_operand_type_t line_number_type =
+ spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER;
+
+ // In NonSemantic.Shader.DebugInfo.100, all constants are IDs of OpConstant,
+ // not literals.
+ if (setId ==
+ context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo())
+ line_number_type = spv_operand_type_t::SPV_OPERAND_TYPE_ID;
uint32_t line_number = 0;
if (line == nullptr) {
auto* lexical_scope_inst = GetDbgInst(scope.GetLexicalScope());
if (lexical_scope_inst == nullptr) return kNoInlinedAt;
- OpenCLDebugInfo100Instructions debug_opcode =
- lexical_scope_inst->GetOpenCL100DebugOpcode();
+ CommonDebugInfoInstructions debug_opcode =
+ lexical_scope_inst->GetCommonDebugOpcode();
switch (debug_opcode) {
- case OpenCLDebugInfo100DebugFunction:
+ case CommonDebugInfoDebugFunction:
line_number = lexical_scope_inst->GetSingleWordOperand(
kLineOperandIndexDebugFunction);
break;
- case OpenCLDebugInfo100DebugLexicalBlock:
+ case CommonDebugInfoDebugLexicalBlock:
line_number = lexical_scope_inst->GetSingleWordOperand(
kLineOperandIndexDebugLexicalBlock);
break;
- case OpenCLDebugInfo100DebugTypeComposite:
- case OpenCLDebugInfo100DebugCompilationUnit:
+ case CommonDebugInfoDebugTypeComposite:
+ case CommonDebugInfoDebugCompilationUnit:
assert(false &&
"DebugTypeComposite and DebugCompilationUnit are lexical "
"scopes, but we inline functions into a function or a block "
@@ -161,6 +192,13 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line,
}
} else {
line_number = line->GetSingleWordOperand(kOpLineOperandLineIndex);
+
+ // If we need the line number as an ID, generate that constant now.
+ if (line_number_type == spv_operand_type_t::SPV_OPERAND_TYPE_ID) {
+ uint32_t line_id =
+ context()->get_constant_mgr()->GetUIntConst(line_number);
+ line_number = line_id;
+ }
}
uint32_t result_id = context()->TakeNextId();
@@ -168,13 +206,10 @@ uint32_t DebugInfoManager::CreateDebugInlinedAt(const Instruction* line,
context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
result_id,
{
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {context()
- ->get_feature_mgr()
- ->GetExtInstImportId_OpenCL100DebugInfo()}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {setId}},
{spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
- {static_cast<uint32_t>(OpenCLDebugInfo100DebugInlinedAt)}},
- {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}},
+ {static_cast<uint32_t>(CommonDebugInfoDebugInlinedAt)}},
+ {line_number_type, {line_number}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {scope.GetLexicalScope()}},
}));
// |scope| already has DebugInlinedAt. We put the existing DebugInlinedAt
@@ -257,19 +292,34 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() {
if (deref_operation_ != nullptr) return deref_operation_;
uint32_t result_id = context()->TakeNextId();
- std::unique_ptr<Instruction> deref_operation(new Instruction(
- context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
- result_id,
- {
- {SPV_OPERAND_TYPE_ID,
- {context()
- ->get_feature_mgr()
- ->GetExtInstImportId_OpenCL100DebugInfo()}},
- {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
- {static_cast<uint32_t>(OpenCLDebugInfo100DebugOperation)}},
- {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION,
- {static_cast<uint32_t>(OpenCLDebugInfo100Deref)}},
- }));
+ std::unique_ptr<Instruction> deref_operation;
+
+ if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) {
+ deref_operation = std::unique_ptr<Instruction>(new Instruction(
+ context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
+ result_id,
+ {
+ {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}},
+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
+ {static_cast<uint32_t>(OpenCLDebugInfo100DebugOperation)}},
+ {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION,
+ {static_cast<uint32_t>(OpenCLDebugInfo100Deref)}},
+ }));
+ } else {
+ uint32_t deref_id = context()->get_constant_mgr()->GetUIntConst(
+ NonSemanticShaderDebugInfo100Deref);
+
+ deref_operation = std::unique_ptr<Instruction>(
+ new Instruction(context(), SpvOpExtInst,
+ context()->get_type_mgr()->GetVoidTypeId(), result_id,
+ {
+ {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}},
+ {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
+ {static_cast<uint32_t>(
+ NonSemanticShaderDebugInfo100DebugOperation)}},
+ {SPV_OPERAND_TYPE_ID, {deref_id}},
+ }));
+ }
// Add to the front of |ext_inst_debuginfo_|.
deref_operation_ =
@@ -283,8 +333,7 @@ Instruction* DebugInfoManager::GetDebugOperationWithDeref() {
}
Instruction* DebugInfoManager::DerefDebugExpression(Instruction* dbg_expr) {
- assert(dbg_expr->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugExpression);
+ assert(dbg_expr->GetCommonDebugOpcode() == CommonDebugInfoDebugExpression);
std::unique_ptr<Instruction> deref_expr(dbg_expr->Clone(context()));
deref_expr->SetResultId(context()->TakeNextId());
deref_expr->InsertOperand(
@@ -306,12 +355,9 @@ Instruction* DebugInfoManager::GetDebugInfoNone() {
context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
result_id,
{
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {context()
- ->get_feature_mgr()
- ->GetExtInstImportId_OpenCL100DebugInfo()}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}},
{spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
- {static_cast<uint32_t>(OpenCLDebugInfo100DebugInfoNone)}},
+ {static_cast<uint32_t>(CommonDebugInfoDebugInfoNone)}},
}));
// Add to the front of |ext_inst_debuginfo_|.
@@ -333,12 +379,9 @@ Instruction* DebugInfoManager::GetEmptyDebugExpression() {
context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
result_id,
{
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {context()
- ->get_feature_mgr()
- ->GetExtInstImportId_OpenCL100DebugInfo()}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}},
{spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
- {static_cast<uint32_t>(OpenCLDebugInfo100DebugExpression)}},
+ {static_cast<uint32_t>(CommonDebugInfoDebugExpression)}},
}));
// Add to the front of |ext_inst_debuginfo_|.
@@ -355,8 +398,7 @@ Instruction* DebugInfoManager::GetEmptyDebugExpression() {
Instruction* DebugInfoManager::GetDebugInlinedAt(uint32_t dbg_inlined_at_id) {
auto* inlined_at = GetDbgInst(dbg_inlined_at_id);
if (inlined_at == nullptr) return nullptr;
- if (inlined_at->GetOpenCL100DebugOpcode() !=
- OpenCLDebugInfo100DebugInlinedAt) {
+ if (inlined_at->GetCommonDebugOpcode() != CommonDebugInfoDebugInlinedAt) {
return nullptr;
}
return inlined_at;
@@ -403,23 +445,23 @@ bool DebugInfoManager::KillDebugDeclares(uint32_t variable_id) {
uint32_t DebugInfoManager::GetParentScope(uint32_t child_scope) {
auto dbg_scope_itr = id_to_dbg_inst_.find(child_scope);
assert(dbg_scope_itr != id_to_dbg_inst_.end());
- OpenCLDebugInfo100Instructions debug_opcode =
- dbg_scope_itr->second->GetOpenCL100DebugOpcode();
+ CommonDebugInfoInstructions debug_opcode =
+ dbg_scope_itr->second->GetCommonDebugOpcode();
uint32_t parent_scope = kNoDebugScope;
switch (debug_opcode) {
- case OpenCLDebugInfo100DebugFunction:
+ case CommonDebugInfoDebugFunction:
parent_scope = dbg_scope_itr->second->GetSingleWordOperand(
kDebugFunctionOperandParentIndex);
break;
- case OpenCLDebugInfo100DebugLexicalBlock:
+ case CommonDebugInfoDebugLexicalBlock:
parent_scope = dbg_scope_itr->second->GetSingleWordOperand(
kDebugLexicalBlockOperandParentIndex);
break;
- case OpenCLDebugInfo100DebugTypeComposite:
+ case CommonDebugInfoDebugTypeComposite:
parent_scope = dbg_scope_itr->second->GetSingleWordOperand(
kDebugTypeCompositeOperandParentIndex);
break;
- case OpenCLDebugInfo100DebugCompilationUnit:
+ case CommonDebugInfoDebugCompilationUnit:
// DebugCompilationUnit does not have a parent scope.
break;
default:
@@ -513,8 +555,7 @@ Instruction* DebugInfoManager::AddDebugValueForDecl(
std::unique_ptr<Instruction> dbg_val(dbg_decl->Clone(context()));
dbg_val->SetResultId(context()->TakeNextId());
- dbg_val->SetInOperand(kExtInstInstructionInIdx,
- {OpenCLDebugInfo100DebugValue});
+ dbg_val->SetInOperand(kExtInstInstructionInIdx, {CommonDebugInfoDebugValue});
dbg_val->SetOperand(kDebugDeclareOperandVariableIndex, {value_id});
dbg_val->SetOperand(kDebugValueOperandExpressionIndex,
{GetEmptyDebugExpression()->result_id()});
@@ -532,9 +573,20 @@ Instruction* DebugInfoManager::AddDebugValueForDecl(
return added_dbg_val;
}
+uint32_t DebugInfoManager::GetVulkanDebugOperation(Instruction* inst) {
+ assert(inst->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugOperation &&
+ "inst must be Vulkan DebugOperation");
+ return context()
+ ->get_constant_mgr()
+ ->GetConstantFromInst(context()->get_def_use_mgr()->GetDef(
+ inst->GetSingleWordOperand(kDebugOperationOperandOperationIndex)))
+ ->GetU32();
+}
+
uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare(
Instruction* inst) {
- if (inst->GetOpenCL100DebugOpcode() != OpenCLDebugInfo100DebugValue) return 0;
+ if (inst->GetCommonDebugOpcode() != CommonDebugInfoDebugValue) return 0;
auto* expr =
GetDbgInst(inst->GetSingleWordOperand(kDebugValueOperandExpressionIndex));
@@ -544,9 +596,19 @@ uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare(
auto* operation = GetDbgInst(
expr->GetSingleWordOperand(kDebugExpressOperandOperationIndex));
if (operation == nullptr) return 0;
- if (operation->GetSingleWordOperand(kDebugOperationOperandOperationIndex) !=
- OpenCLDebugInfo100Deref) {
- return 0;
+
+ // OpenCL.DebugInfo.100 contains a literal for the operation, Vulkan uses an
+ // OpConstant.
+ if (inst->IsOpenCL100DebugInstr()) {
+ if (operation->GetSingleWordOperand(kDebugOperationOperandOperationIndex) !=
+ OpenCLDebugInfo100Deref) {
+ return 0;
+ }
+ } else {
+ uint32_t operation_const = GetVulkanDebugOperation(operation);
+ if (operation_const != NonSemanticShaderDebugInfo100Deref) {
+ return 0;
+ }
}
uint32_t var_id =
@@ -567,8 +629,8 @@ uint32_t DebugInfoManager::GetVariableIdOfDebugValueUsedForDeclare(
}
bool DebugInfoManager::IsDebugDeclare(Instruction* instr) {
- if (!instr->IsOpenCL100DebugInstr()) return false;
- return instr->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugDeclare ||
+ if (!instr->IsCommonDebugInstr()) return false;
+ return instr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare ||
GetVariableIdOfDebugValueUsedForDeclare(instr) != 0;
}
@@ -615,14 +677,13 @@ void DebugInfoManager::AnalyzeDebugInst(Instruction* inst) {
users.insert(inst);
}
- if (!inst->IsOpenCL100DebugInstr()) return;
+ if (!inst->IsCommonDebugInstr()) return;
RegisterDbgInst(inst);
- if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction) {
- assert(GetDebugFunction(inst->GetSingleWordOperand(
- kDebugFunctionOperandFunctionIndex)) == nullptr &&
- "Two DebugFunction instruction exists for a single OpFunction.");
+ if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugFunction ||
+ inst->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
RegisterDbgFunction(inst);
}
@@ -633,8 +694,17 @@ void DebugInfoManager::AnalyzeDebugInst(Instruction* inst) {
deref_operation_ = inst;
}
+ if (deref_operation_ == nullptr &&
+ inst->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugOperation) {
+ uint32_t operation_const = GetVulkanDebugOperation(inst);
+ if (operation_const == NonSemanticShaderDebugInfo100Deref) {
+ deref_operation_ = inst;
+ }
+ }
+
if (debug_info_none_inst_ == nullptr &&
- inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugInfoNone) {
+ inst->GetCommonDebugOpcode() == CommonDebugInfoDebugInfoNone) {
debug_info_none_inst_ = inst;
}
@@ -642,7 +712,7 @@ void DebugInfoManager::AnalyzeDebugInst(Instruction* inst) {
empty_debug_expr_inst_ = inst;
}
- if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugDeclare) {
+ if (inst->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare) {
uint32_t var_id =
inst->GetSingleWordOperand(kDebugDeclareOperandVariableIndex);
RegisterDbgDeclare(var_id, inst);
@@ -655,8 +725,8 @@ void DebugInfoManager::AnalyzeDebugInst(Instruction* inst) {
void DebugInfoManager::ConvertDebugGlobalToLocalVariable(
Instruction* dbg_global_var, Instruction* local_var) {
- if (dbg_global_var->GetOpenCL100DebugOpcode() !=
- OpenCLDebugInfo100DebugGlobalVariable) {
+ if (dbg_global_var->GetCommonDebugOpcode() !=
+ CommonDebugInfoDebugGlobalVariable) {
return;
}
assert(local_var->opcode() == SpvOpVariable ||
@@ -664,7 +734,7 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable(
// Convert |dbg_global_var| to DebugLocalVariable
dbg_global_var->SetInOperand(kExtInstInstructionInIdx,
- {OpenCLDebugInfo100DebugLocalVariable});
+ {CommonDebugInfoDebugLocalVariable});
auto flags = dbg_global_var->GetSingleWordOperand(
kDebugGlobalVariableOperandFlagsIndex);
for (uint32_t i = dbg_global_var->NumInOperands() - 1;
@@ -680,20 +750,20 @@ void DebugInfoManager::ConvertDebugGlobalToLocalVariable(
context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(),
context()->TakeNextId(),
{
- {spv_operand_type_t::SPV_OPERAND_TYPE_ID,
- {context()
- ->get_feature_mgr()
- ->GetExtInstImportId_OpenCL100DebugInfo()}},
+ {spv_operand_type_t::SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}},
{spv_operand_type_t::SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER,
- {static_cast<uint32_t>(OpenCLDebugInfo100DebugDeclare)}},
+ {static_cast<uint32_t>(CommonDebugInfoDebugDeclare)}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
{dbg_global_var->result_id()}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {local_var->result_id()}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID,
{GetEmptyDebugExpression()->result_id()}},
}));
- auto* added_dbg_decl =
- local_var->NextNode()->InsertBefore(std::move(new_dbg_decl));
+ // Must insert after all OpVariables in block
+ Instruction* insert_before = local_var;
+ while (insert_before->opcode() == SpvOpVariable)
+ insert_before = insert_before->NextNode();
+ auto* added_dbg_decl = insert_before->InsertBefore(std::move(new_dbg_decl));
if (context()->AreAnalysesValid(IRContext::Analysis::kAnalysisDefUse))
context()->get_def_use_mgr()->AnalyzeInstDefUse(added_dbg_decl);
if (context()->AreAnalysesValid(
@@ -713,7 +783,7 @@ void DebugInfoManager::AnalyzeDebugInsts(Module& module) {
// list.
if (empty_debug_expr_inst_ != nullptr &&
empty_debug_expr_inst_->PreviousNode() != nullptr &&
- empty_debug_expr_inst_->PreviousNode()->IsOpenCL100DebugInstr()) {
+ empty_debug_expr_inst_->PreviousNode()->IsCommonDebugInstr()) {
empty_debug_expr_inst_->InsertBefore(
&*context()->module()->ext_inst_debuginfo_begin());
}
@@ -722,7 +792,7 @@ void DebugInfoManager::AnalyzeDebugInsts(Module& module) {
// list.
if (debug_info_none_inst_ != nullptr &&
debug_info_none_inst_->PreviousNode() != nullptr &&
- debug_info_none_inst_->PreviousNode()->IsOpenCL100DebugInstr()) {
+ debug_info_none_inst_->PreviousNode()->IsCommonDebugInstr()) {
debug_info_none_inst_->InsertBefore(
&*context()->module()->ext_inst_debuginfo_begin());
}
@@ -740,7 +810,7 @@ void DebugInfoManager::ClearDebugInfo(Instruction* instr) {
inlinedat_id_to_users_itr->second.erase(instr);
}
- if (instr == nullptr || !instr->IsOpenCL100DebugInstr()) {
+ if (instr == nullptr || !instr->IsCommonDebugInstr()) {
return;
}
@@ -751,9 +821,15 @@ void DebugInfoManager::ClearDebugInfo(Instruction* instr) {
instr->GetSingleWordOperand(kDebugFunctionOperandFunctionIndex);
fn_id_to_dbg_fn_.erase(fn_id);
}
+ if (instr->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunction) {
+ auto fn_id = instr->GetSingleWordOperand(
+ kDebugFunctionDefinitionOperandOpFunctionIndex);
+ fn_id_to_dbg_fn_.erase(fn_id);
+ }
- if (instr->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugDeclare ||
- instr->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugValue) {
+ if (instr->GetCommonDebugOpcode() == CommonDebugInfoDebugDeclare ||
+ instr->GetCommonDebugOpcode() == CommonDebugInfoDebugValue) {
auto var_or_value_id =
instr->GetSingleWordOperand(kDebugDeclareOperandVariableIndex);
auto dbg_decl_itr = var_id_to_dbg_decl_.find(var_or_value_id);
@@ -767,6 +843,8 @@ void DebugInfoManager::ClearDebugInfo(Instruction* instr) {
for (auto dbg_instr_itr = context()->module()->ext_inst_debuginfo_begin();
dbg_instr_itr != context()->module()->ext_inst_debuginfo_end();
++dbg_instr_itr) {
+ // OpenCL.DebugInfo.100 contains the operation as a literal operand, in
+ // Vulkan it's referenced as an OpConstant.
if (instr != &*dbg_instr_itr &&
dbg_instr_itr->GetOpenCL100DebugOpcode() ==
OpenCLDebugInfo100DebugOperation &&
@@ -775,6 +853,14 @@ void DebugInfoManager::ClearDebugInfo(Instruction* instr) {
OpenCLDebugInfo100Deref) {
deref_operation_ = &*dbg_instr_itr;
break;
+ } else if (instr != &*dbg_instr_itr &&
+ dbg_instr_itr->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugOperation) {
+ uint32_t operation_const = GetVulkanDebugOperation(&*dbg_instr_itr);
+ if (operation_const == NonSemanticShaderDebugInfo100Deref) {
+ deref_operation_ = &*dbg_instr_itr;
+ break;
+ }
}
}
}
@@ -784,9 +870,8 @@ void DebugInfoManager::ClearDebugInfo(Instruction* instr) {
for (auto dbg_instr_itr = context()->module()->ext_inst_debuginfo_begin();
dbg_instr_itr != context()->module()->ext_inst_debuginfo_end();
++dbg_instr_itr) {
- if (instr != &*dbg_instr_itr &&
- dbg_instr_itr->GetOpenCL100DebugOpcode() ==
- OpenCLDebugInfo100DebugInfoNone) {
+ if (instr != &*dbg_instr_itr && dbg_instr_itr->GetCommonDebugOpcode() ==
+ CommonDebugInfoDebugInfoNone) {
debug_info_none_inst_ = &*dbg_instr_itr;
break;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.h
index 776e9baab5d..df34b30f400 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/debug_info_manager.h
@@ -67,8 +67,8 @@ class DebugInlinedAtContext {
std::unordered_map<uint32_t, uint32_t> callee_inlined_at2chain_;
};
-// A class for analyzing, managing, and creating OpenCL.DebugInfo.100 extension
-// instructions.
+// A class for analyzing, managing, and creating OpenCL.DebugInfo.100 and
+// NonSemantic.Shader.DebugInfo.100 extension instructions.
class DebugInfoManager {
public:
// Constructs a debug information manager from the given |context|.
@@ -85,7 +85,7 @@ class DebugInfoManager {
return !(lhs == rhs);
}
- // Analyzes OpenCL.DebugInfo.100 instruction |dbg_inst|.
+ // Analyzes DebugInfo instruction |dbg_inst|.
void AnalyzeDebugInst(Instruction* dbg_inst);
// Creates new DebugInlinedAt and returns its id. Its line operand is the
@@ -164,6 +164,9 @@ class DebugInfoManager {
// Erases |instr| from data structures of this class.
void ClearDebugInfo(Instruction* instr);
+ // Return the opcode for the Vulkan DebugOperation inst
+ uint32_t GetVulkanDebugOperation(Instruction* inst);
+
// Returns the id of Value operand if |inst| is DebugValue who has Deref
// operation and its Value operand is a result id of OpVariable with
// Function storage class. Otherwise, returns 0.
@@ -190,10 +193,13 @@ class DebugInfoManager {
private:
IRContext* context() { return context_; }
- // Analyzes OpenCL.DebugInfo.100 instructions in the given |module| and
+ // Analyzes DebugInfo instructions in the given |module| and
// populates data structures in this class.
void AnalyzeDebugInsts(Module& module);
+ // Get the DebugInfo ExtInstImport Id, or 0 if no DebugInfo is available.
+ uint32_t GetDbgSetImportId();
+
// Returns the debug instruction whose id is |id|. Returns |nullptr| if one
// does not exists.
Instruction* GetDbgInst(uint32_t id);
@@ -230,7 +236,7 @@ class DebugInfoManager {
IRContext* context_;
- // Mapping from ids of OpenCL.DebugInfo.100 extension instructions
+ // Mapping from ids of DebugInfo extension instructions.
// to their Instruction instances.
std::unordered_map<uint32_t, Instruction*> id_to_dbg_inst_;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/def_use_manager.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/def_use_manager.cpp
index 0ec98cae107..394b9fa174c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/def_use_manager.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/def_use_manager.cpp
@@ -58,7 +58,7 @@ void DefUseManager::AnalyzeInstUse(Instruction* inst) {
case SPV_OPERAND_TYPE_SCOPE_ID: {
uint32_t use_id = inst->GetSingleWordOperand(i);
Instruction* def = GetDef(use_id);
- assert(def && "Definition is not registered.");
+ if (!def) assert(false && "Definition is not registered.");
id_to_users_.insert(UserEntry(def, inst));
used_ids->push_back(use_id);
} break;
@@ -71,6 +71,9 @@ void DefUseManager::AnalyzeInstUse(Instruction* inst) {
void DefUseManager::AnalyzeInstDefUse(Instruction* inst) {
AnalyzeInstDef(inst);
AnalyzeInstUse(inst);
+ // Analyze lines last otherwise they will be cleared when inst is
+ // cleared by preceding two calls
+ for (auto& l_inst : inst->dbg_line_insts()) AnalyzeInstDefUse(&l_inst);
}
void DefUseManager::UpdateDefUse(Instruction* inst) {
@@ -224,9 +227,11 @@ void DefUseManager::AnalyzeDefUse(Module* module) {
if (!module) return;
// Analyze all the defs before any uses to catch forward references.
module->ForEachInst(
- std::bind(&DefUseManager::AnalyzeInstDef, this, std::placeholders::_1));
+ std::bind(&DefUseManager::AnalyzeInstDef, this, std::placeholders::_1),
+ true);
module->ForEachInst(
- std::bind(&DefUseManager::AnalyzeInstUse, this, std::placeholders::_1));
+ std::bind(&DefUseManager::AnalyzeInstUse, this, std::placeholders::_1),
+ true);
}
void DefUseManager::ClearInst(Instruction* inst) {
@@ -261,6 +266,16 @@ void DefUseManager::EraseUseRecordsOfOperandIds(const Instruction* inst) {
bool operator==(const DefUseManager& lhs, const DefUseManager& rhs) {
if (lhs.id_to_def_ != rhs.id_to_def_) {
+ for (auto p : lhs.id_to_def_) {
+ if (rhs.id_to_def_.find(p.first) == rhs.id_to_def_.end()) {
+ return false;
+ }
+ }
+ for (auto p : rhs.id_to_def_) {
+ if (lhs.id_to_def_.find(p.first) == lhs.id_to_def_.end()) {
+ return false;
+ }
+ }
return false;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.cpp
index db3abddfd72..39a4a3486ea 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.cpp
@@ -80,8 +80,8 @@ void FeatureManager::AddExtInstImportIds(Module* module) {
extinst_importid_GLSLstd450_ = module->GetExtInstImportId("GLSL.std.450");
extinst_importid_OpenCL100DebugInfo_ =
module->GetExtInstImportId("OpenCL.DebugInfo.100");
- extinst_importid_Vulkan100DebugInfo_ =
- module->GetExtInstImportId("NonSemantic.Vulkan.DebugInfo.100");
+ extinst_importid_Shader100DebugInfo_ =
+ module->GetExtInstImportId("NonSemantic.Shader.DebugInfo.100");
}
bool operator==(const FeatureManager& a, const FeatureManager& b) {
@@ -109,8 +109,8 @@ bool operator==(const FeatureManager& a, const FeatureManager& b) {
return false;
}
- if (a.extinst_importid_Vulkan100DebugInfo_ !=
- b.extinst_importid_Vulkan100DebugInfo_) {
+ if (a.extinst_importid_Shader100DebugInfo_ !=
+ b.extinst_importid_Shader100DebugInfo_) {
return false;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.h
index 4720c6dc426..68c8e9a2306 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/feature_manager.h
@@ -55,8 +55,8 @@ class FeatureManager {
return extinst_importid_OpenCL100DebugInfo_;
}
- uint32_t GetExtInstImportId_Vulkan100DebugInfo() const {
- return extinst_importid_Vulkan100DebugInfo_;
+ uint32_t GetExtInstImportId_Shader100DebugInfo() const {
+ return extinst_importid_Shader100DebugInfo_;
}
friend bool operator==(const FeatureManager& a, const FeatureManager& b);
@@ -97,9 +97,9 @@ class FeatureManager {
// for performance.
uint32_t extinst_importid_OpenCL100DebugInfo_ = 0;
- // Common NonSemanticVulkan100DebugInfo external instruction import ids,
+ // Common NonSemanticShader100DebugInfo external instruction import ids,
// cached for performance.
- uint32_t extinst_importid_Vulkan100DebugInfo_ = 0;
+ uint32_t extinst_importid_Shader100DebugInfo_ = 0;
};
} // namespace opt
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp
index e3e926c3a52..886c03fd686 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp
@@ -14,6 +14,7 @@
#include "source/opt/folding_rules.h"
+#include <climits>
#include <limits>
#include <memory>
#include <utility>
@@ -523,7 +524,8 @@ uint32_t PerformFloatingPointOperation(analysis::ConstantManager* const_mgr,
float fval = val.getAsFloat(); \
if (!IsValidResult(fval)) return 0; \
words = val.GetWords(); \
- } static_assert(true, "require extra semicolon")
+ } \
+ static_assert(true, "require extra semicolon")
switch (opcode) {
case SpvOpFMul:
FOLD_OP(*);
@@ -558,24 +560,19 @@ uint32_t PerformIntegerOperation(analysis::ConstantManager* const_mgr,
uint32_t width = type->AsInteger()->width();
assert(width == 32 || width == 64);
std::vector<uint32_t> words;
-#define FOLD_OP(op) \
- if (width == 64) { \
- if (type->IsSigned()) { \
- int64_t val = input1->GetS64() op input2->GetS64(); \
- words = ExtractInts(static_cast<uint64_t>(val)); \
- } else { \
- uint64_t val = input1->GetU64() op input2->GetU64(); \
- words = ExtractInts(val); \
- } \
- } else { \
- if (type->IsSigned()) { \
- int32_t val = input1->GetS32() op input2->GetS32(); \
- words.push_back(static_cast<uint32_t>(val)); \
- } else { \
- uint32_t val = input1->GetU32() op input2->GetU32(); \
- words.push_back(val); \
- } \
- } static_assert(true, "require extra semicalon")
+ // Regardless of the sign of the constant, folding is performed on an unsigned
+ // interpretation of the constant data. This avoids signed integer overflow
+ // while folding, and works because sign is irrelevant for the IAdd, ISub and
+ // IMul instructions.
+#define FOLD_OP(op) \
+ if (width == 64) { \
+ uint64_t val = input1->GetU64() op input2->GetU64(); \
+ words = ExtractInts(val); \
+ } else { \
+ uint32_t val = input1->GetU32() op input2->GetU32(); \
+ words.push_back(val); \
+ } \
+ static_assert(true, "require extra semicolon")
switch (opcode) {
case SpvOpIMul:
FOLD_OP(*);
@@ -967,12 +964,11 @@ FoldingRule MergeDivMulArithmetic() {
// Fold divides of a constant and a negation.
// Cases:
// (-x) / 2 = x / -2
-// 2 / (-x) = 2 / -x
+// 2 / (-x) = -2 / x
FoldingRule MergeDivNegateArithmetic() {
return [](IRContext* context, Instruction* inst,
const std::vector<const analysis::Constant*>& constants) {
- assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv ||
- inst->opcode() == SpvOpUDiv);
+ assert(inst->opcode() == SpvOpFDiv || inst->opcode() == SpvOpSDiv);
analysis::ConstantManager* const_mgr = context->get_constant_mgr();
const analysis::Type* type =
context->get_type_mgr()->GetType(inst->type_id());
@@ -1468,90 +1464,121 @@ FoldingRule IntMultipleBy1() {
};
}
-FoldingRule CompositeConstructFeedingExtract() {
- return [](IRContext* context, Instruction* inst,
- const std::vector<const analysis::Constant*>&) {
- // If the input to an OpCompositeExtract is an OpCompositeConstruct,
- // then we can simply use the appropriate element in the construction.
- assert(inst->opcode() == SpvOpCompositeExtract &&
- "Wrong opcode. Should be OpCompositeExtract.");
- analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
- analysis::TypeManager* type_mgr = context->get_type_mgr();
-
- // If there are no index operands, then this rule cannot do anything.
- if (inst->NumInOperands() <= 1) {
- return false;
- }
+// Returns the number of elements that the |index|th in operand in |inst|
+// contributes to the result of |inst|. |inst| must be an
+// OpCompositeConstructInstruction.
+uint32_t GetNumOfElementsContributedByOperand(IRContext* context,
+ const Instruction* inst,
+ uint32_t index) {
+ assert(inst->opcode() == SpvOpCompositeConstruct);
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ analysis::TypeManager* type_mgr = context->get_type_mgr();
+
+ analysis::Vector* result_type =
+ type_mgr->GetType(inst->type_id())->AsVector();
+ if (result_type == nullptr) {
+ // If the result of the OpCompositeConstruct is not a vector then every
+ // operands corresponds to a single element in the result.
+ return 1;
+ }
- uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
- Instruction* cinst = def_use_mgr->GetDef(cid);
+ // If the result type is a vector then the operands are either scalars or
+ // vectors. If it is a scalar, then it corresponds to a single element. If it
+ // is a vector, then each element in the vector will be an element in the
+ // result.
+ uint32_t id = inst->GetSingleWordInOperand(index);
+ Instruction* def = def_use_mgr->GetDef(id);
+ analysis::Vector* type = type_mgr->GetType(def->type_id())->AsVector();
+ if (type == nullptr) {
+ return 1;
+ }
+ return type->element_count();
+}
- if (cinst->opcode() != SpvOpCompositeConstruct) {
- return false;
- }
+// Returns the in-operands for an OpCompositeExtract instruction that are needed
+// to extract the |result_index|th element in the result of |inst| without using
+// the result of |inst|. Returns the empty vector if |result_index| is
+// out-of-bounds. |inst| must be an |OpCompositeConstruct| instruction.
+std::vector<Operand> GetExtractOperandsForElementOfCompositeConstruct(
+ IRContext* context, const Instruction* inst, uint32_t result_index) {
+ assert(inst->opcode() == SpvOpCompositeConstruct);
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+ analysis::TypeManager* type_mgr = context->get_type_mgr();
- std::vector<Operand> operands;
- analysis::Type* composite_type = type_mgr->GetType(cinst->type_id());
- if (composite_type->AsVector() == nullptr) {
- // Get the element being extracted from the OpCompositeConstruct
- // Since it is not a vector, it is simple to extract the single element.
- uint32_t element_index = inst->GetSingleWordInOperand(1);
- uint32_t element_id = cinst->GetSingleWordInOperand(element_index);
- operands.push_back({SPV_OPERAND_TYPE_ID, {element_id}});
-
- // Add the remaining indices for extraction.
- for (uint32_t i = 2; i < inst->NumInOperands(); ++i) {
- operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER,
- {inst->GetSingleWordInOperand(i)}});
- }
+ analysis::Type* result_type = type_mgr->GetType(inst->type_id());
+ if (result_type->AsVector() == nullptr) {
+ uint32_t id = inst->GetSingleWordInOperand(result_index);
+ return {Operand(SPV_OPERAND_TYPE_ID, {id})};
+ }
- } else {
- // With vectors we have to handle the case where it is concatenating
- // vectors.
- assert(inst->NumInOperands() == 2 &&
- "Expecting a vector of scalar values.");
-
- uint32_t element_index = inst->GetSingleWordInOperand(1);
- for (uint32_t construct_index = 0;
- construct_index < cinst->NumInOperands(); ++construct_index) {
- uint32_t element_id = cinst->GetSingleWordInOperand(construct_index);
- Instruction* element_def = def_use_mgr->GetDef(element_id);
- analysis::Vector* element_type =
- type_mgr->GetType(element_def->type_id())->AsVector();
- if (element_type) {
- uint32_t vector_size = element_type->element_count();
- if (vector_size <= element_index) {
- // The element we want comes after this vector.
- element_index -= vector_size;
- } else {
- // We want an element of this vector.
- operands.push_back({SPV_OPERAND_TYPE_ID, {element_id}});
- operands.push_back(
- {SPV_OPERAND_TYPE_LITERAL_INTEGER, {element_index}});
- break;
- }
- } else {
- if (element_index == 0) {
- // This is a scalar, and we this is the element we are extracting.
- operands.push_back({SPV_OPERAND_TYPE_ID, {element_id}});
- break;
- } else {
- // Skip over this scalar value.
- --element_index;
- }
- }
+ // If the result type is a vector, then vector operands are concatenated.
+ uint32_t total_element_count = 0;
+ for (uint32_t idx = 0; idx < inst->NumInOperands(); ++idx) {
+ uint32_t element_count =
+ GetNumOfElementsContributedByOperand(context, inst, idx);
+ total_element_count += element_count;
+ if (result_index < total_element_count) {
+ std::vector<Operand> operands;
+ uint32_t id = inst->GetSingleWordInOperand(idx);
+ Instruction* operand_def = def_use_mgr->GetDef(id);
+ analysis::Type* operand_type = type_mgr->GetType(operand_def->type_id());
+
+ operands.push_back({SPV_OPERAND_TYPE_ID, {id}});
+ if (operand_type->AsVector()) {
+ uint32_t start_index_of_id = total_element_count - element_count;
+ uint32_t index_into_id = result_index - start_index_of_id;
+ operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {index_into_id}});
}
+ return operands;
}
+ }
+ return {};
+}
+
+bool CompositeConstructFeedingExtract(
+ IRContext* context, Instruction* inst,
+ const std::vector<const analysis::Constant*>&) {
+ // If the input to an OpCompositeExtract is an OpCompositeConstruct,
+ // then we can simply use the appropriate element in the construction.
+ assert(inst->opcode() == SpvOpCompositeExtract &&
+ "Wrong opcode. Should be OpCompositeExtract.");
+ analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr();
+
+ // If there are no index operands, then this rule cannot do anything.
+ if (inst->NumInOperands() <= 1) {
+ return false;
+ }
+
+ uint32_t cid = inst->GetSingleWordInOperand(kExtractCompositeIdInIdx);
+ Instruction* cinst = def_use_mgr->GetDef(cid);
+
+ if (cinst->opcode() != SpvOpCompositeConstruct) {
+ return false;
+ }
+
+ uint32_t index_into_result = inst->GetSingleWordInOperand(1);
+ std::vector<Operand> operands =
+ GetExtractOperandsForElementOfCompositeConstruct(context, cinst,
+ index_into_result);
+ if (operands.empty()) {
+ return false;
+ }
+
+ // Add the remaining indices for extraction.
+ for (uint32_t i = 2; i < inst->NumInOperands(); ++i) {
+ operands.push_back(
+ {SPV_OPERAND_TYPE_LITERAL_INTEGER, {inst->GetSingleWordInOperand(i)}});
+ }
+
+ if (operands.size() == 1) {
// If there were no extra indices, then we have the final object. No need
- // to extract even more.
- if (operands.size() == 1) {
- inst->SetOpcode(SpvOpCopyObject);
- }
+ // to extract any more.
+ inst->SetOpcode(SpvOpCopyObject);
+ }
- inst->SetInOperands(std::move(operands));
- return true;
- };
+ inst->SetInOperands(std::move(operands));
+ return true;
}
// If the OpCompositeConstruct is simply putting back together elements that
@@ -2510,7 +2537,7 @@ void FoldingRules::AddFoldingRules() {
rules_[SpvOpCompositeConstruct].push_back(CompositeExtractFeedingConstruct);
rules_[SpvOpCompositeExtract].push_back(InsertFeedingExtract());
- rules_[SpvOpCompositeExtract].push_back(CompositeConstructFeedingExtract());
+ rules_[SpvOpCompositeExtract].push_back(CompositeConstructFeedingExtract);
rules_[SpvOpCompositeExtract].push_back(VectorShuffleFeedingExtract());
rules_[SpvOpCompositeExtract].push_back(FMixFeedingExtract());
@@ -2572,8 +2599,6 @@ void FoldingRules::AddFoldingRules() {
rules_[SpvOpStore].push_back(StoringUndef());
- rules_[SpvOpUDiv].push_back(MergeDivNegateArithmetic());
-
rules_[SpvOpVectorShuffle].push_back(VectorShuffleFeedingShuffle());
rules_[SpvOpImageSampleImplicitLod].push_back(UpdateImageOperands());
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/if_conversion.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/if_conversion.cpp
index 4284069a8b5..492066177fd 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/if_conversion.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/if_conversion.cpp
@@ -129,6 +129,7 @@ Pass::Status IfConversion::Process() {
Instruction* select = builder.AddSelect(phi->type_id(), condition,
true_value->result_id(),
false_value->result_id());
+ context()->get_def_use_mgr()->AnalyzeInstDefUse(select);
select->UpdateDebugInfoFrom(phi);
context()->ReplaceAllUsesWith(phi->result_id(), select->result_id());
to_kill.push_back(phi);
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp
index a6bdaaff0c6..2cc31258e3c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp
@@ -92,7 +92,7 @@ void InlinePass::AddStore(uint32_t ptr_id, uint32_t val_id,
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}},
{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {val_id}}}));
if (line_inst != nullptr) {
- newStore->dbg_line_insts().push_back(*line_inst);
+ newStore->AddDebugLine(line_inst);
}
newStore->SetDebugScope(dbg_scope);
(*block_ptr)->AddInstruction(std::move(newStore));
@@ -106,7 +106,7 @@ void InlinePass::AddLoad(uint32_t type_id, uint32_t resultId, uint32_t ptr_id,
new Instruction(context(), SpvOpLoad, type_id, resultId,
{{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {ptr_id}}}));
if (line_inst != nullptr) {
- newLoad->dbg_line_insts().push_back(*line_inst);
+ newLoad->AddDebugLine(line_inst);
}
newLoad->SetDebugScope(dbg_scope);
(*block_ptr)->AddInstruction(std::move(newLoad));
@@ -405,8 +405,8 @@ bool InlinePass::InlineEntryBlock(
while (callee_inst_itr != callee_first_block->end()) {
// Don't inline function definition links, the calling function is not a
// definition.
- if (callee_inst_itr->GetVulkan100DebugOpcode() ==
- NonSemanticVulkanDebugInfo100DebugFunctionDefinition) {
+ if (callee_inst_itr->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
++callee_inst_itr;
continue;
}
@@ -441,6 +441,11 @@ std::unique_ptr<BasicBlock> InlinePass::InlineBasicBlocks(
auto tail_inst_itr = callee_block_itr->end();
for (auto inst_itr = callee_block_itr->begin(); inst_itr != tail_inst_itr;
++inst_itr) {
+ // Don't inline function definition links, the calling function is not a
+ // definition
+ if (inst_itr->GetShader100DebugOpcode() ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition)
+ continue;
if (!InlineSingleInstruction(
callee2caller, new_blk_ptr.get(), &*inst_itr,
context()->get_debug_info_mgr()->BuildDebugInlinedAtChain(
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
index 06acc7ea559..e2336d3601d 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.cpp
@@ -130,13 +130,48 @@ 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 SpvOpTypeFloat:
+ case SpvOpTypeInt:
+ case SpvOpTypeVector:
+ return GetTypeLength(type_id);
+ case SpvOpTypeMatrix:
+ return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
+ case SpvOpTypeArray:
+ case SpvOpTypeRuntimeArray:
+ return GetTypeAlignment(type_inst->GetSingleWordInOperand(0));
+ case SpvOpTypeStruct: {
+ 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 SpvOpTypePointer:
+ assert(type_inst->GetSingleWordInOperand(0) ==
+ SpvStorageClassPhysicalStorageBufferEXT &&
+ "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 SpvOpTypeFloat:
case SpvOpTypeInt:
return type_inst->GetSingleWordInOperand(0) / 8u;
- case SpvOpTypeVector:
+ case SpvOpTypeVector: {
+ 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 SpvOpTypeMatrix:
return type_inst->GetSingleWordInOperand(1) *
GetTypeLength(type_inst->GetSingleWordInOperand(0));
@@ -145,8 +180,29 @@ uint32_t InstBuffAddrCheckPass::GetTypeLength(uint32_t type_id) {
SpvStorageClassPhysicalStorageBufferEXT &&
"unexpected pointer type");
return 8u;
+ case SpvOpTypeArray: {
+ uint32_t const_id = type_inst->GetSingleWordInOperand(1);
+ Instruction* const_inst = get_def_use_mgr()->GetDef(const_id);
+ uint32_t cnt = const_inst->GetSingleWordInOperand(0);
+ return cnt * GetTypeLength(type_inst->GetSingleWordInOperand(0));
+ }
+ case SpvOpTypeStruct: {
+ 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;
+ });
+ return len;
+ }
+ case SpvOpTypeRuntimeArray:
default:
- assert(false && "unexpected buffer reference type");
+ assert(false && "unexpected type");
return 0;
}
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.h
index ec7bb6846f9..a82322395a6 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/inst_buff_addr_check_pass.h
@@ -28,7 +28,9 @@ namespace opt {
// external design of this class may change as the layer evolves.
class InstBuffAddrCheckPass : public InstrumentPass {
public:
- // Preferred interface
+ // For test harness only
+ InstBuffAddrCheckPass() : InstrumentPass(7, 23, kInstValidationIdBuffAddr) {}
+ // For all other interfaces
InstBuffAddrCheckPass(uint32_t desc_set, uint32_t shader_id)
: InstrumentPass(desc_set, shader_id, kInstValidationIdBuffAddr) {}
@@ -40,8 +42,12 @@ class InstBuffAddrCheckPass : public InstrumentPass {
const char* name() const override { return "inst-bindless-check-pass"; }
private:
- // Return byte length of type |type_id|. Must be int, float, vector, matrix
- // or physical pointer.
+ // 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);
// Add |type_id| param to |input_func| and add id to |param_vec|.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.cpp
index 577c0a67cbc..665b72f0024 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.cpp
@@ -16,7 +16,6 @@
#include <initializer_list>
-#include "NonSemanticVulkanDebugInfo100.h"
#include "OpenCLDebugInfo100.h"
#include "source/disassemble.h"
#include "source/opt/fold.h"
@@ -33,7 +32,7 @@ const uint32_t kLoadBaseIndex = 0;
const uint32_t kPointerTypeStorageClassIndex = 0;
const uint32_t kTypeImageSampledIndex = 5;
-// Constants for OpenCL.DebugInfo.100 / NonSemantic.Vulkan.DebugInfo.100
+// Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100
// extension instructions.
const uint32_t kExtInstSetIdInIdx = 0;
const uint32_t kExtInstInstructionInIdx = 1;
@@ -74,8 +73,6 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
unique_id_(c->TakeNextUniqueId()),
dbg_line_insts_(std::move(dbg_line)),
dbg_scope_(kNoDebugScope, kNoInlinedAt) {
- assert((!IsDebugLineInst(opcode_) || dbg_line.empty()) &&
- "Op(No)Line attaching to Op(No)Line found");
for (uint32_t i = 0; i < inst.num_operands; ++i) {
const auto& current_payload = inst.operands[i];
std::vector<uint32_t> words(
@@ -83,6 +80,8 @@ Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
inst.words + current_payload.offset + current_payload.num_words);
operands_.emplace_back(current_payload.type, std::move(words));
}
+ assert((!IsLineInst() || dbg_line.empty()) &&
+ "Op(No)Line attaching to Op(No)Line found");
}
Instruction::Instruction(IRContext* c, const spv_parsed_instruction_t& inst,
@@ -159,6 +158,10 @@ Instruction* Instruction::Clone(IRContext* c) const {
clone->unique_id_ = c->TakeNextUniqueId();
clone->operands_ = operands_;
clone->dbg_line_insts_ = dbg_line_insts_;
+ for (auto& i : clone->dbg_line_insts_) {
+ i.unique_id_ = c->TakeNextUniqueId();
+ if (i.IsDebugLineInst()) i.SetResultId(c->TakeNextId());
+ }
clone->dbg_scope_ = dbg_scope_;
return clone;
}
@@ -512,7 +515,7 @@ void Instruction::UpdateLexicalScope(uint32_t scope) {
for (auto& i : dbg_line_insts_) {
i.dbg_scope_.SetLexicalScope(scope);
}
- if (!IsDebugLineInst(opcode()) &&
+ if (!IsLineInst() &&
context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) {
context()->get_debug_info_mgr()->AnalyzeDebugInst(this);
}
@@ -523,24 +526,61 @@ void Instruction::UpdateDebugInlinedAt(uint32_t new_inlined_at) {
for (auto& i : dbg_line_insts_) {
i.dbg_scope_.SetInlinedAt(new_inlined_at);
}
- if (!IsDebugLineInst(opcode()) &&
+ if (!IsLineInst() &&
context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) {
context()->get_debug_info_mgr()->AnalyzeDebugInst(this);
}
}
+void Instruction::ClearDbgLineInsts() {
+ if (context()->AreAnalysesValid(IRContext::kAnalysisDefUse)) {
+ auto def_use_mgr = context()->get_def_use_mgr();
+ for (auto& l_inst : dbg_line_insts_) def_use_mgr->ClearInst(&l_inst);
+ }
+ clear_dbg_line_insts();
+}
+
void Instruction::UpdateDebugInfoFrom(const Instruction* from) {
if (from == nullptr) return;
- clear_dbg_line_insts();
+ ClearDbgLineInsts();
if (!from->dbg_line_insts().empty())
- dbg_line_insts().push_back(from->dbg_line_insts().back());
+ AddDebugLine(&from->dbg_line_insts().back());
SetDebugScope(from->GetDebugScope());
- if (!IsDebugLineInst(opcode()) &&
+ if (!IsLineInst() &&
context()->AreAnalysesValid(IRContext::kAnalysisDebugInfo)) {
context()->get_debug_info_mgr()->AnalyzeDebugInst(this);
}
}
+void Instruction::AddDebugLine(const Instruction* inst) {
+ dbg_line_insts_.push_back(*inst);
+ dbg_line_insts_.back().unique_id_ = context()->TakeNextUniqueId();
+ if (inst->IsDebugLineInst())
+ dbg_line_insts_.back().SetResultId(context_->TakeNextId());
+ if (context()->AreAnalysesValid(IRContext::kAnalysisDefUse))
+ context()->get_def_use_mgr()->AnalyzeInstDefUse(&dbg_line_insts_.back());
+}
+
+bool Instruction::IsDebugLineInst() const {
+ NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode();
+ return ((ext_opt == NonSemanticShaderDebugInfo100DebugLine) ||
+ (ext_opt == NonSemanticShaderDebugInfo100DebugNoLine));
+}
+
+bool Instruction::IsLineInst() const { return IsLine() || IsNoLine(); }
+
+bool Instruction::IsLine() const {
+ if (opcode() == SpvOpLine) return true;
+ NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode();
+ return ext_opt == NonSemanticShaderDebugInfo100DebugLine;
+}
+
+bool Instruction::IsNoLine() const {
+ if (opcode() == SpvOpNoLine) return true;
+ NonSemanticShaderDebugInfo100Instructions ext_opt = GetShader100DebugOpcode();
+ return ext_opt == NonSemanticShaderDebugInfo100DebugNoLine;
+}
+
Instruction* Instruction::InsertBefore(std::unique_ptr<Instruction>&& inst) {
inst.get()->InsertBefore(this);
return inst.release();
@@ -624,22 +664,22 @@ OpenCLDebugInfo100Instructions Instruction::GetOpenCL100DebugOpcode() const {
GetSingleWordInOperand(kExtInstInstructionInIdx));
}
-NonSemanticVulkanDebugInfo100Instructions Instruction::GetVulkan100DebugOpcode()
+NonSemanticShaderDebugInfo100Instructions Instruction::GetShader100DebugOpcode()
const {
if (opcode() != SpvOpExtInst) {
- return NonSemanticVulkanDebugInfo100InstructionsMax;
+ return NonSemanticShaderDebugInfo100InstructionsMax;
}
- if (!context()->get_feature_mgr()->GetExtInstImportId_Vulkan100DebugInfo()) {
- return NonSemanticVulkanDebugInfo100InstructionsMax;
+ if (!context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo()) {
+ return NonSemanticShaderDebugInfo100InstructionsMax;
}
if (GetSingleWordInOperand(kExtInstSetIdInIdx) !=
- context()->get_feature_mgr()->GetExtInstImportId_Vulkan100DebugInfo()) {
- return NonSemanticVulkanDebugInfo100InstructionsMax;
+ context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo()) {
+ return NonSemanticShaderDebugInfo100InstructionsMax;
}
- return NonSemanticVulkanDebugInfo100Instructions(
+ return NonSemanticShaderDebugInfo100Instructions(
GetSingleWordInOperand(kExtInstInstructionInIdx));
}
@@ -650,16 +690,16 @@ CommonDebugInfoInstructions Instruction::GetCommonDebugOpcode() const {
const uint32_t opencl_set_id =
context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo();
- const uint32_t vulkan_set_id =
- context()->get_feature_mgr()->GetExtInstImportId_Vulkan100DebugInfo();
+ const uint32_t shader_set_id =
+ context()->get_feature_mgr()->GetExtInstImportId_Shader100DebugInfo();
- if (!opencl_set_id && !vulkan_set_id) {
+ if (!opencl_set_id && !shader_set_id) {
return CommonDebugInfoInstructionsMax;
}
const uint32_t used_set_id = GetSingleWordInOperand(kExtInstSetIdInIdx);
- if (used_set_id != opencl_set_id && used_set_id != vulkan_set_id) {
+ if (used_set_id != opencl_set_id && used_set_id != shader_set_id) {
return CommonDebugInfoInstructionsMax;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.h
index 7cdfc44dd88..c962e509a37 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/instruction.h
@@ -22,7 +22,7 @@
#include <utility>
#include <vector>
-#include "NonSemanticVulkanDebugInfo100.h"
+#include "NonSemanticShaderDebugInfo100.h"
#include "OpenCLDebugInfo100.h"
#include "source/common_debug_info.h"
#include "source/latest_version_glsl_std_450_header.h"
@@ -252,11 +252,6 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// Clear line-related debug instructions attached to this instruction.
void clear_dbg_line_insts() { dbg_line_insts_.clear(); }
- // Set line-related debug instructions.
- void set_dbg_line_insts(const std::vector<Instruction>& lines) {
- dbg_line_insts_ = lines;
- }
-
// Same semantics as in the base class except the list the InstructionList
// containing |pos| will now assume ownership of |this|.
// inline void MoveBefore(Instruction* pos);
@@ -306,8 +301,21 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// Sets DebugScope.
inline void SetDebugScope(const DebugScope& scope);
inline const DebugScope& GetDebugScope() const { return dbg_scope_; }
+ // Add debug line inst. Renew result id if Debug[No]Line
+ void AddDebugLine(const Instruction* inst);
// Updates DebugInlinedAt of DebugScope and OpLine.
void UpdateDebugInlinedAt(uint32_t new_inlined_at);
+ // Clear line-related debug instructions attached to this instruction
+ // along with def-use entries.
+ void ClearDbgLineInsts();
+ // Return true if Shader100:Debug[No]Line
+ bool IsDebugLineInst() const;
+ // Return true if Op[No]Line or Shader100:Debug[No]Line
+ bool IsLineInst() const;
+ // Return true if OpLine or Shader100:DebugLine
+ bool IsLine() const;
+ // Return true if OpNoLine or Shader100:DebugNoLine
+ bool IsNoLine() const;
inline uint32_t GetDebugInlinedAt() const {
return dbg_scope_.GetInlinedAt();
}
@@ -552,13 +560,13 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
// OpenCLDebugInfo100InstructionsMax.
OpenCLDebugInfo100Instructions GetOpenCL100DebugOpcode() const;
- // Returns debug opcode of a NonSemantic.Vulkan.DebugInfo.100 instruction. If
- // it is not a NonSemantic.Vulkan.DebugInfo.100 instruction, just returns
- // NonSemanticVulkanDebugInfo100InstructionsMax.
- NonSemanticVulkanDebugInfo100Instructions GetVulkan100DebugOpcode() const;
+ // Returns debug opcode of an NonSemantic.Shader.DebugInfo.100 instruction. If
+ // it is not an NonSemantic.Shader.DebugInfo.100 instruction, just return
+ // NonSemanticShaderDebugInfo100InstructionsMax.
+ NonSemanticShaderDebugInfo100Instructions GetShader100DebugOpcode() const;
// Returns debug opcode of an OpenCL.100.DebugInfo or
- // NonSemantic.Vulkan.DebugInfo.100 instruction. Since these overlap, we
+ // NonSemantic.Shader.DebugInfo.100 instruction. Since these overlap, we
// return the OpenCLDebugInfo code
CommonDebugInfoInstructions GetCommonDebugOpcode() const;
@@ -566,10 +574,11 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
bool IsOpenCL100DebugInstr() const {
return GetOpenCL100DebugOpcode() != OpenCLDebugInfo100InstructionsMax;
}
- // Returns true if it is a NonSemantic.Vulkan.DebugInfo.100 instruction.
- bool IsVulkan100DebugInstr() const {
- return GetVulkan100DebugOpcode() !=
- NonSemanticVulkanDebugInfo100InstructionsMax;
+
+ // Returns true if it is an NonSemantic.Shader.DebugInfo.100 instruction.
+ bool IsShader100DebugInstr() const {
+ return GetShader100DebugOpcode() !=
+ NonSemanticShaderDebugInfo100InstructionsMax;
}
bool IsCommonDebugInstr() const {
return GetCommonDebugOpcode() != CommonDebugInfoInstructionsMax;
@@ -608,9 +617,9 @@ class Instruction : public utils::IntrusiveNodeBase<Instruction> {
uint32_t unique_id_; // Unique instruction id
// All logical operands, including result type id and result id.
OperandList operands_;
- // Opline and OpNoLine instructions preceding this instruction. Note that for
- // Instructions representing OpLine or OpNonLine itself, this field should be
- // empty.
+ // Op[No]Line or Debug[No]Line instructions preceding this instruction. Note
+ // that for Instructions representing Op[No]Line or Debug[No]Line themselves,
+ // this field should be empty.
std::vector<Instruction> dbg_line_insts_;
// DebugScope that wraps this instruction.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp
index 90873461864..612a831add6 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp
@@ -30,7 +30,7 @@ static const int kSpvDecorateBuiltinInIdx = 2;
static const int kEntryPointInterfaceInIdx = 3;
static const int kEntryPointFunctionIdInIdx = 1;
-// Constants for OpenCL.DebugInfo.100 / NonSemantic.Vulkan.DebugInfo.100
+// Constants for OpenCL.DebugInfo.100 / NonSemantic.Shader.DebugInfo.100
// extension instructions.
static const uint32_t kDebugFunctionOperandFunctionIndex = 13;
static const uint32_t kDebugGlobalVariableOperandVariableIndex = 11;
@@ -171,7 +171,9 @@ Instruction* IRContext::KillInst(Instruction* inst) {
KillOperandFromDebugInstructions(inst);
if (AreAnalysesValid(kAnalysisDefUse)) {
- get_def_use_mgr()->ClearInst(inst);
+ analysis::DefUseManager* def_use_mgr = get_def_use_mgr();
+ def_use_mgr->ClearInst(inst);
+ for (auto& l_inst : inst->dbg_line_insts()) def_use_mgr->ClearInst(&l_inst);
}
if (AreAnalysesValid(kAnalysisInstrToBlockMapping)) {
instr_to_block_.erase(inst);
@@ -218,6 +220,8 @@ Instruction* IRContext::KillInst(Instruction* inst) {
void IRContext::CollectNonSemanticTree(
Instruction* inst, std::unordered_set<Instruction*>* to_kill) {
if (!inst->HasResultId()) return;
+ // Debug[No]Line result id is not used, so we are done
+ if (inst->IsDebugLineInst()) return;
std::vector<Instruction*> work_list;
std::unordered_set<Instruction*> seen;
work_list.push_back(inst);
@@ -930,7 +934,7 @@ void IRContext::EmitErrorMessage(std::string message, Instruction* inst) {
while (line_inst != nullptr) { // Stop at the beginning of the basic block.
if (!line_inst->dbg_line_insts().empty()) {
line_inst = &line_inst->dbg_line_insts().back();
- if (line_inst->opcode() == SpvOpNoLine) {
+ if (line_inst->IsNoLine()) {
line_inst = nullptr;
}
break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h
index 3b89d85c263..658534760d3 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h
@@ -98,6 +98,7 @@ class IRContext {
module_(new Module()),
consumer_(std::move(c)),
def_use_mgr_(nullptr),
+ feature_mgr_(nullptr),
valid_analyses_(kAnalysisNone),
constant_mgr_(nullptr),
type_mgr_(nullptr),
@@ -116,6 +117,7 @@ class IRContext {
module_(std::move(m)),
consumer_(std::move(c)),
def_use_mgr_(nullptr),
+ feature_mgr_(nullptr),
valid_analyses_(kAnalysisNone),
type_mgr_(nullptr),
id_to_name_(nullptr),
@@ -769,6 +771,8 @@ class IRContext {
// The instruction decoration manager for |module_|.
std::unique_ptr<analysis::DecorationManager> decoration_mgr_;
+
+ // The feature manager for |module_|.
std::unique_ptr<FeatureManager> feature_mgr_;
// A map from instructions to the basic block they belong to. This mapping is
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp
index bfdd59b3d79..a82b530e6c0 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp
@@ -17,9 +17,9 @@
#include <utility>
#include "DebugInfo.h"
-#include "NonSemanticVulkanDebugInfo100.h"
#include "OpenCLDebugInfo100.h"
#include "source/ext_inst.h"
+#include "source/opt/ir_context.h"
#include "source/opt/log.h"
#include "source/opt/reflect.h"
#include "source/util/make_unique.h"
@@ -38,25 +38,37 @@ IrLoader::IrLoader(const MessageConsumer& consumer, Module* m)
inst_index_(0),
last_dbg_scope_(kNoDebugScope, kNoInlinedAt) {}
+bool IsLineInst(const spv_parsed_instruction_t* inst) {
+ const auto opcode = static_cast<SpvOp>(inst->opcode);
+ if (IsOpLineInst(opcode)) return true;
+ if (opcode != SpvOpExtInst) return false;
+ if (inst->ext_inst_type != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100)
+ return false;
+ const uint32_t ext_inst_index = inst->words[kExtInstSetIndex];
+ const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
+ NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
+ return ext_inst_key == NonSemanticShaderDebugInfo100DebugLine ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine;
+}
+
bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
++inst_index_;
- const auto opcode = static_cast<SpvOp>(inst->opcode);
- if (IsDebugLineInst(opcode)) {
+ if (IsLineInst(inst)) {
module()->SetContainsDebugInfo();
last_line_inst_.reset();
- dbg_line_info_.push_back(
- Instruction(module()->context(), *inst, last_dbg_scope_));
+ dbg_line_info_.emplace_back(module()->context(), *inst, last_dbg_scope_);
return true;
}
// If it is a DebugScope or DebugNoScope of debug extension, we do not
// create a new instruction, but simply keep the information in
// struct DebugScope.
+ const auto opcode = static_cast<SpvOp>(inst->opcode);
if (opcode == SpvOpExtInst && spvExtInstIsDebugInfo(inst->ext_inst_type)) {
const uint32_t ext_inst_index = inst->words[kExtInstSetIndex];
if (inst->ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
inst->ext_inst_type ==
- SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100) {
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
const CommonDebugInfoInstructions ext_inst_key =
CommonDebugInfoInstructions(ext_inst_index);
if (ext_inst_key == CommonDebugInfoDebugScope) {
@@ -97,14 +109,20 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
new Instruction(module()->context(), *inst, std::move(dbg_line_info_)));
if (!spv_inst->dbg_line_insts().empty()) {
if (extra_line_tracking_ &&
- (spv_inst->dbg_line_insts().back().opcode() != SpvOpNoLine)) {
+ (!spv_inst->dbg_line_insts().back().IsNoLine())) {
last_line_inst_ = std::unique_ptr<Instruction>(
spv_inst->dbg_line_insts().back().Clone(module()->context()));
+ if (last_line_inst_->IsDebugLineInst())
+ last_line_inst_->SetResultId(module()->context()->TakeNextId());
}
dbg_line_info_.clear();
} else if (last_line_inst_ != nullptr) {
last_line_inst_->SetDebugScope(last_dbg_scope_);
spv_inst->dbg_line_insts().push_back(*last_line_inst_);
+ last_line_inst_ = std::unique_ptr<Instruction>(
+ spv_inst->dbg_line_insts().back().Clone(module()->context()));
+ if (last_line_inst_->IsDebugLineInst())
+ last_line_inst_->SetResultId(module()->context()->TakeNextId());
}
const char* src = source_.c_str();
@@ -243,15 +261,15 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) {
}
}
} else if (inst->ext_inst_type ==
- SPV_EXT_INST_TYPE_NONSEMANTIC_VULKAN_DEBUGINFO_100) {
- const NonSemanticVulkanDebugInfo100Instructions ext_inst_key =
- NonSemanticVulkanDebugInfo100Instructions(ext_inst_index);
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
+ const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
+ NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
switch (ext_inst_key) {
- case NonSemanticVulkanDebugInfo100DebugDeclare:
- case NonSemanticVulkanDebugInfo100DebugValue:
- case NonSemanticVulkanDebugInfo100DebugScope:
- case NonSemanticVulkanDebugInfo100DebugNoScope:
- case NonSemanticVulkanDebugInfo100DebugFunctionDefinition: {
+ case NonSemanticShaderDebugInfo100DebugDeclare:
+ case NonSemanticShaderDebugInfo100DebugValue:
+ case NonSemanticShaderDebugInfo100DebugScope:
+ case NonSemanticShaderDebugInfo100DebugNoScope:
+ case NonSemanticShaderDebugInfo100DebugFunctionDefinition: {
if (block_ == nullptr) { // Inside function but outside blocks
Errorf(consumer_, src, loc,
"Debug info extension instruction found inside function "
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp
index e8dbdfc41f6..da9ba8cc01e 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_access_chain_convert_pass.cpp
@@ -333,6 +333,20 @@ bool LocalAccessChainConvertPass::AllExtensionsSupported() const {
if (extensions_allowlist_.find(extName) == extensions_allowlist_.end())
return false;
}
+ // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise
+ // around unknown extended
+ // instruction sets even if they are non-semantic
+ for (auto& inst : context()->module()->ext_inst_imports()) {
+ assert(inst.opcode() == SpvOpExtInstImport &&
+ "Expecting an import of an extension's instruction set.");
+ const char* extension_name =
+ reinterpret_cast<const char*>(&inst.GetInOperand(0).words[0]);
+ if (0 == std::strncmp(extension_name, "NonSemantic.", 12) &&
+ 0 != std::strncmp(extension_name, "NonSemantic.Shader.DebugInfo.100",
+ 32)) {
+ return false;
+ }
+ }
return true;
}
@@ -421,6 +435,7 @@ void LocalAccessChainConvertPass::InitExtensions() {
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
"SPV_EXT_shader_image_int64",
+ "SPV_KHR_non_semantic_info",
});
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp
index a742e3b1e6b..80b081dca9f 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_block_elim_pass.cpp
@@ -188,6 +188,20 @@ bool LocalSingleBlockLoadStoreElimPass::AllExtensionsSupported() const {
if (extensions_allowlist_.find(extName) == extensions_allowlist_.end())
return false;
}
+ // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise
+ // around unknown extended
+ // instruction sets even if they are non-semantic
+ for (auto& inst : context()->module()->ext_inst_imports()) {
+ assert(inst.opcode() == SpvOpExtInstImport &&
+ "Expecting an import of an extension's instruction set.");
+ const char* extension_name =
+ reinterpret_cast<const char*>(&inst.GetInOperand(0).words[0]);
+ if (0 == std::strncmp(extension_name, "NonSemantic.", 12) &&
+ 0 != std::strncmp(extension_name, "NonSemantic.Shader.DebugInfo.100",
+ 32)) {
+ return false;
+ }
+ }
return true;
}
@@ -273,6 +287,7 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() {
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
"SPV_EXT_shader_image_int64",
+ "SPV_KHR_non_semantic_info",
});
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp
index 9701d10e244..a32db3b7606 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/local_single_store_elim_pass.cpp
@@ -53,6 +53,20 @@ bool LocalSingleStoreElimPass::AllExtensionsSupported() const {
if (extensions_allowlist_.find(extName) == extensions_allowlist_.end())
return false;
}
+ // only allow NonSemantic.Shader.DebugInfo.100, we cannot safely optimise
+ // around unknown extended
+ // instruction sets even if they are non-semantic
+ for (auto& inst : context()->module()->ext_inst_imports()) {
+ assert(inst.opcode() == SpvOpExtInstImport &&
+ "Expecting an import of an extension's instruction set.");
+ const char* extension_name =
+ reinterpret_cast<const char*>(&inst.GetInOperand(0).words[0]);
+ if (0 == std::strncmp(extension_name, "NonSemantic.", 12) &&
+ 0 != std::strncmp(extension_name, "NonSemantic.Shader.DebugInfo.100",
+ 32)) {
+ return false;
+ }
+ }
return true;
}
@@ -126,6 +140,7 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() {
"SPV_KHR_subgroup_uniform_control_flow",
"SPV_KHR_integer_dot_product",
"SPV_EXT_shader_image_int64",
+ "SPV_KHR_non_semantic_info",
});
}
bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/loop_unroller.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/loop_unroller.cpp
index df68bd20ed5..bf622500cb2 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/loop_unroller.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/loop_unroller.cpp
@@ -760,7 +760,7 @@ void LoopUnrollerUtilsImpl::FoldConditionBlock(BasicBlock* condition_block,
IRContext::Analysis::kAnalysisInstrToBlockMapping);
Instruction* new_branch = builder.AddBranch(new_target);
- new_branch->set_dbg_line_insts(lines);
+ if (!lines.empty()) new_branch->AddDebugLine(&lines.back());
new_branch->SetDebugScope(scope);
}
@@ -873,6 +873,10 @@ void LoopUnrollerUtilsImpl::AssignNewResultIds(BasicBlock* basic_block) {
def_use_mgr->AnalyzeInstDefUse(basic_block->GetLabelInst());
for (Instruction& inst : *basic_block) {
+ // Do def/use analysis on new lines
+ for (auto& line : inst.dbg_line_insts())
+ def_use_mgr->AnalyzeInstDefUse(&line);
+
uint32_t old_id = inst.result_id();
// Ignore stores etc.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.cpp
index 6585012f2e8..f97defbd6f9 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.cpp
@@ -151,16 +151,15 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
this](const Instruction* i) {
// Skip emitting line instructions between merge and branch instructions.
auto opcode = i->opcode();
- if (between_merge_and_branch &&
- (opcode == SpvOpLine || opcode == SpvOpNoLine)) {
+ if (between_merge_and_branch && i->IsLineInst()) {
return;
}
between_merge_and_branch = false;
if (last_line_inst != nullptr) {
- // If the current instruction is OpLine and it is the same with
- // the last line instruction that is still effective (can be applied
+ // If the current instruction is OpLine or DebugLine and it is the same
+ // as the last line instruction that is still effective (can be applied
// to the next instruction), we skip writing the current instruction.
- if (opcode == SpvOpLine) {
+ if (i->IsLine()) {
uint32_t operand_index = 0;
if (last_line_inst->WhileEachInOperand(
[&operand_index, i](const uint32_t* word) {
@@ -169,11 +168,22 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
})) {
return;
}
- } else if (opcode != SpvOpNoLine && i->dbg_line_insts().empty()) {
+ } else if (!i->IsNoLine() && i->dbg_line_insts().empty()) {
// If the current instruction does not have the line information,
// the last line information is not effective any more. Emit OpNoLine
- // to specify it.
- binary->push_back((1 << 16) | static_cast<uint16_t>(SpvOpNoLine));
+ // or DebugNoLine to specify it.
+ uint32_t shader_set_id = context()
+ ->get_feature_mgr()
+ ->GetExtInstImportId_Shader100DebugInfo();
+ if (shader_set_id != 0) {
+ binary->push_back((5 << 16) | static_cast<uint16_t>(SpvOpExtInst));
+ binary->push_back(context()->get_type_mgr()->GetVoidTypeId());
+ binary->push_back(context()->TakeNextId());
+ binary->push_back(shader_set_id);
+ binary->push_back(NonSemanticShaderDebugInfo100DebugNoLine);
+ } else {
+ binary->push_back((1 << 16) | static_cast<uint16_t>(SpvOpNoLine));
+ }
last_line_inst = nullptr;
}
}
@@ -181,7 +191,7 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
if (opcode == SpvOpLabel) {
between_label_and_phi_var = true;
} else if (opcode != SpvOpVariable && opcode != SpvOpPhi &&
- opcode != SpvOpLine && opcode != SpvOpNoLine) {
+ !spvtools::opt::IsOpLineInst(opcode)) {
between_label_and_phi_var = false;
}
@@ -190,7 +200,7 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
if (scope != last_scope) {
// Can only emit nonsemantic instructions after all phi instructions
// in a block so don't emit scope instructions before phi instructions
- // for Vulkan.NonSemantic.DebugInfo.100.
+ // for NonSemantic.Shader.DebugInfo.100.
if (!between_label_and_phi_var ||
context()
->get_feature_mgr()
@@ -206,18 +216,19 @@ void Module::ToBinary(std::vector<uint32_t>* binary, bool skip_nop) const {
i->ToBinaryWithoutAttachedDebugInsts(binary);
}
// Update the last line instruction.
- if (spvOpcodeIsBlockTerminator(opcode) || opcode == SpvOpNoLine) {
+ if (spvOpcodeIsBlockTerminator(opcode) || i->IsNoLine()) {
last_line_inst = nullptr;
} else if (opcode == SpvOpLoopMerge || opcode == SpvOpSelectionMerge) {
between_merge_and_branch = true;
last_line_inst = nullptr;
- } else if (opcode == SpvOpLine) {
+ } else if (i->IsLine()) {
last_line_inst = i;
}
};
ForEachInst(write_inst, true);
- // We create new instructions for DebugScope. The bound must be updated.
+ // We create new instructions for DebugScope and DebugNoLine. The bound must
+ // be updated.
binary->data()[bound_idx] = header_.bound;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.h
index 43b55ae1557..0360b7d5b40 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/module.h
@@ -104,7 +104,7 @@ class Module {
inline void AddDebug3Inst(std::unique_ptr<Instruction> d);
// Appends a debug info extension (OpenCL.DebugInfo.100,
- // NonSemantic.Vulkan.DebugInfo.100, or DebugInfo) instruction to this module.
+ // NonSemantic.Shader.DebugInfo.100, or DebugInfo) instruction to this module.
inline void AddExtInstDebugInfo(std::unique_ptr<Instruction> d);
// Appends an annotation instruction to this module.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp
index 69103b26c9a..990be2e4360 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp
@@ -385,7 +385,23 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
} else if (pass_name == "loop-invariant-code-motion") {
RegisterPass(CreateLoopInvariantCodeMotionPass());
} else if (pass_name == "reduce-load-size") {
- RegisterPass(CreateReduceLoadSizePass());
+ if (pass_args.size() == 0) {
+ RegisterPass(CreateReduceLoadSizePass());
+ } else {
+ double load_replacement_threshold = 0.9;
+ if (pass_args.find_first_not_of(".0123456789") == std::string::npos) {
+ load_replacement_threshold = atof(pass_args.c_str());
+ }
+
+ if (load_replacement_threshold >= 0) {
+ RegisterPass(CreateReduceLoadSizePass(load_replacement_threshold));
+ } else {
+ Error(consumer(), nullptr, {},
+ "--reduce-load-size must have no arguments or a non-negative "
+ "double argument");
+ return false;
+ }
+ }
} else if (pass_name == "redundancy-elimination") {
RegisterPass(CreateRedundancyEliminationPass());
} else if (pass_name == "private-to-local") {
@@ -401,22 +417,22 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
RegisterPass(CreateSimplificationPass());
RegisterPass(CreateDeadBranchElimPass());
RegisterPass(CreateBlockMergePass());
- RegisterPass(CreateAggressiveDCEPass());
+ 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());
+ 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());
+ RegisterPass(CreateAggressiveDCEPass(true));
} else if (pass_name == "inst-buff-addr-check") {
RegisterPass(CreateInstBuffAddrCheckPass(7, 23));
- RegisterPass(CreateAggressiveDCEPass());
+ RegisterPass(CreateAggressiveDCEPass(true));
} else if (pass_name == "convert-relaxed-to-half") {
RegisterPass(CreateConvertRelaxedToHalfPass());
} else if (pass_name == "relax-float-ops") {
@@ -499,6 +515,26 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag) {
RegisterPass(CreateAmdExtToKhrPass());
} else if (pass_name == "interpolate-fixup") {
RegisterPass(CreateInterpolateFixupPass());
+ } else if (pass_name == "convert-to-sampled-image") {
+ if (pass_args.size() > 0) {
+ auto descriptor_set_binding_pairs =
+ opt::ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString(
+ pass_args.c_str());
+ if (!descriptor_set_binding_pairs) {
+ Errorf(consumer(), nullptr, {},
+ "Invalid argument for --convert-to-sampled-image: %s",
+ pass_args.c_str());
+ return false;
+ }
+ RegisterPass(CreateConvertToSampledImagePass(
+ std::move(*descriptor_set_binding_pairs)));
+ } else {
+ Errorf(consumer(), nullptr, {},
+ "Invalid pairs of descriptor set and binding '%s'. Expected a "
+ "string of <descriptor set>:<binding> pairs.",
+ pass_args.c_str());
+ return false;
+ }
} else {
Errorf(consumer(), nullptr, {},
"Unknown flag '--%s'. Use --help for a list of valid flags",
@@ -726,9 +762,9 @@ Optimizer::PassToken CreateLocalMultiStoreElimPass() {
MakeUnique<opt::SSARewritePass>());
}
-Optimizer::PassToken CreateAggressiveDCEPass() {
+Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface) {
return MakeUnique<Optimizer::PassToken::Impl>(
- MakeUnique<opt::AggressiveDCEPass>());
+ MakeUnique<opt::AggressiveDCEPass>(preserve_interface));
}
Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass() {
@@ -859,9 +895,10 @@ Optimizer::PassToken CreateVectorDCEPass() {
return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::VectorDCE>());
}
-Optimizer::PassToken CreateReduceLoadSizePass() {
+Optimizer::PassToken CreateReduceLoadSizePass(
+ double load_replacement_threshold) {
return MakeUnique<Optimizer::PassToken::Impl>(
- MakeUnique<opt::ReduceLoadSize>());
+ MakeUnique<opt::ReduceLoadSize>(load_replacement_threshold));
}
Optimizer::PassToken CreateCombineAccessChainsPass() {
@@ -940,4 +977,11 @@ Optimizer::PassToken CreateInterpolateFixupPass() {
MakeUnique<opt::InterpFixupPass>());
}
+Optimizer::PassToken CreateConvertToSampledImagePass(
+ const std::vector<opt::DescriptorSetAndBinding>&
+ descriptor_set_binding_pairs) {
+ return MakeUnique<Optimizer::PassToken::Impl>(
+ MakeUnique<opt::ConvertToSampledImagePass>(descriptor_set_binding_pairs));
+}
+
} // namespace spvtools
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/pass.cpp
index 09b78af933c..017aad10f90 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/pass.cpp
@@ -43,8 +43,8 @@ Pass::Status Pass::Run(IRContext* ctx) {
if (status == Status::SuccessWithChange) {
ctx->InvalidateAnalysesExceptFor(GetPreservedAnalyses());
}
- assert((status == Status::Failure || ctx->IsConsistent()) &&
- "An analysis in the context is out of date.");
+ if (!(status == Status::Failure || ctx->IsConsistent()))
+ assert(false && "An analysis in the context is out of date.");
return status;
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/passes.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/passes.h
index aeae44494d6..da837f2ab84 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/passes.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/passes.h
@@ -26,6 +26,7 @@
#include "source/opt/combine_access_chains.h"
#include "source/opt/compact_ids_pass.h"
#include "source/opt/convert_to_half_pass.h"
+#include "source/opt/convert_to_sampled_image_pass.h"
#include "source/opt/copy_prop_arrays.h"
#include "source/opt/dead_branch_elim_pass.h"
#include "source/opt/dead_insert_elim_pass.h"
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp
index 87d2c4c089f..e9b8087489c 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.cpp
@@ -27,7 +27,6 @@ namespace {
const uint32_t kExtractCompositeIdInIdx = 0;
const uint32_t kVariableStorageClassInIdx = 0;
const uint32_t kLoadPointerInIdx = 0;
-const double kThreshold = 0.9;
} // namespace
@@ -151,6 +150,8 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) {
bool should_replace = false;
if (all_elements_used) {
should_replace = false;
+ } else if (1.0 <= replacement_threshold_) {
+ should_replace = true;
} else {
analysis::ConstantManager* const_mgr = context()->get_constant_mgr();
analysis::TypeManager* type_mgr = context()->get_type_mgr();
@@ -172,7 +173,7 @@ bool ReduceLoadSize::ShouldReplaceExtract(Instruction* inst) {
}
double percent_used = static_cast<double>(elements_used.size()) /
static_cast<double>(total_size);
- should_replace = (percent_used < kThreshold);
+ should_replace = (percent_used < replacement_threshold_);
}
should_replace_cache_[op_inst->result_id()] = should_replace;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.h
index ccac49be6d0..b323845366a 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reduce_load_size.h
@@ -27,6 +27,9 @@ namespace opt {
// See optimizer.hpp for documentation.
class ReduceLoadSize : public Pass {
public:
+ explicit ReduceLoadSize(double replacement_threshold)
+ : replacement_threshold_(replacement_threshold) {}
+
const char* name() const override { return "reduce-load-size"; }
Status Process() override;
@@ -54,6 +57,11 @@ class ReduceLoadSize : public Pass {
// on the load feeding |inst|.
bool ShouldReplaceExtract(Instruction* inst);
+ // Threshold to determine whether we have to replace the load or not. If the
+ // ratio of the used components of the load is less than the threshold, we
+ // replace the load.
+ double replacement_threshold_;
+
// Maps the result id of an OpLoad instruction to the result of whether or
// not the OpCompositeExtract that use the id should be replaced.
std::unordered_map<uint32_t, bool> should_replace_cache_;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reflect.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reflect.h
index c7d46df548f..d300fe5dbef 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reflect.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/reflect.h
@@ -34,7 +34,7 @@ inline bool IsDebug2Inst(SpvOp opcode) {
inline bool IsDebug3Inst(SpvOp opcode) {
return opcode == SpvOpModuleProcessed;
}
-inline bool IsDebugLineInst(SpvOp opcode) {
+inline bool IsOpLineInst(SpvOp opcode) {
return opcode == SpvOpLine || opcode == SpvOpNoLine;
}
inline bool IsAnnotationInst(SpvOp opcode) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp
index 38b7539bf97..e3b9d3e4034 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/replace_invalid_opc.cpp
@@ -71,10 +71,10 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function,
function->ForEachInst(
[model, &modified, &last_line_dbg_inst, this](Instruction* inst) {
// Track the debug information so we can have a meaningful message.
- if (inst->opcode() == SpvOpLabel || inst->opcode() == SpvOpNoLine) {
+ if (inst->opcode() == SpvOpLabel || inst->IsNoLine()) {
last_line_dbg_inst = nullptr;
return;
- } else if (inst->opcode() == SpvOpLine) {
+ } else if (inst->IsLine()) {
last_line_dbg_inst = inst;
return;
}
@@ -100,8 +100,18 @@ bool ReplaceInvalidOpcodePass::RewriteFunction(Function* function,
ReplaceInstruction(inst, nullptr, 0, 0);
} else {
// Get the name of the source file.
- Instruction* file_name = context()->get_def_use_mgr()->GetDef(
- last_line_dbg_inst->GetSingleWordInOperand(0));
+ uint32_t file_name_id = 0;
+ if (last_line_dbg_inst->opcode() == SpvOpLine) {
+ file_name_id = last_line_dbg_inst->GetSingleWordInOperand(0);
+ } else { // Shader100::DebugLine
+ uint32_t debug_source_id =
+ last_line_dbg_inst->GetSingleWordInOperand(2);
+ Instruction* debug_source_inst =
+ context()->get_def_use_mgr()->GetDef(debug_source_id);
+ file_name_id = debug_source_inst->GetSingleWordInOperand(2);
+ }
+ Instruction* file_name =
+ context()->get_def_use_mgr()->GetDef(file_name_id);
const char* source = reinterpret_cast<const char*>(
&file_name->GetInOperand(0).words[0]);
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp
index 8adca7b9aea..8bc04991e1d 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.cpp
@@ -27,6 +27,7 @@
static const uint32_t kDebugValueOperandValueIndex = 5;
static const uint32_t kDebugValueOperandExpressionIndex = 6;
+static const uint32_t kDebugDeclareOperandVariableIndex = 5;
namespace spvtools {
namespace opt {
@@ -172,10 +173,14 @@ bool ScalarReplacementPass::ReplaceWholeDebugDeclare(
// Add DebugValue instruction with Indexes operand and Deref operation.
int32_t idx = 0;
for (const auto* var : replacements) {
+ Instruction* insert_before = var->NextNode();
+ while (insert_before->opcode() == SpvOpVariable)
+ insert_before = insert_before->NextNode();
+ assert(insert_before != nullptr && "unexpected end of list");
Instruction* added_dbg_value =
context()->get_debug_info_mgr()->AddDebugValueForDecl(
dbg_decl, /*value_id=*/var->result_id(),
- /*insert_before=*/var->NextNode(), /*scope_and_line=*/dbg_decl);
+ /*insert_before=*/insert_before, /*scope_and_line=*/dbg_decl);
if (added_dbg_value == nullptr) return false;
added_dbg_value->AddOperand(
@@ -864,6 +869,11 @@ bool ScalarReplacementPass::CheckUsesRelaxed(const Instruction* inst) const {
case SpvOpImageTexelPointer:
if (!CheckImageTexelPointer(index)) ok = false;
break;
+ case SpvOpExtInst:
+ if (user->GetCommonDebugOpcode() != CommonDebugInfoDebugDeclare ||
+ !CheckDebugDeclare(index))
+ ok = false;
+ break;
default:
ok = false;
break;
@@ -894,6 +904,12 @@ bool ScalarReplacementPass::CheckStore(const Instruction* inst,
return false;
return true;
}
+
+bool ScalarReplacementPass::CheckDebugDeclare(uint32_t index) const {
+ if (index != kDebugDeclareOperandVariableIndex) return false;
+ return true;
+}
+
bool ScalarReplacementPass::IsLargerThanSizeLimit(uint64_t length) const {
if (max_num_elements_ == 0) {
return false;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h
index 9e9f0739488..0928830c07a 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/scalar_replacement_pass.h
@@ -142,6 +142,9 @@ class ScalarReplacementPass : public Pass {
// of |inst| and the store is not to volatile memory.
bool CheckStore(const Instruction* inst, uint32_t index) const;
+ // Returns true if the DebugDeclare can be scalarized at |index|.
+ bool CheckDebugDeclare(uint32_t index) const;
+
// Returns true if |index| is the pointer operand of an OpImageTexelPointer
// instruction.
bool CheckImageTexelPointer(uint32_t index) const;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.cpp
index 3c9f9446a39..28d94a076f3 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.cpp
@@ -110,7 +110,11 @@ void VectorDCE::MarkExtractUseAsLive(const Instruction* current_inst,
if (current_inst->NumInOperands() < 2) {
new_item.components = live_elements;
} else {
- new_item.components.Set(current_inst->GetSingleWordInOperand(1));
+ uint32_t element_index = current_inst->GetSingleWordInOperand(1);
+ uint32_t item_size = GetVectorComponentCount(operand_inst->type_id());
+ if (element_index < item_size) {
+ new_item.components.Set(element_index);
+ }
}
AddItemToWorkListIfNeeded(new_item, live_components, work_list);
}
@@ -176,10 +180,10 @@ void VectorDCE::MarkVectorShuffleUsesAsLive(
second_operand.instruction =
def_use_mgr->GetDef(current_item.instruction->GetSingleWordInOperand(1));
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
- analysis::Vector* first_type =
- type_mgr->GetType(first_operand.instruction->type_id())->AsVector();
- uint32_t size_of_first_operand = first_type->element_count();
+ uint32_t size_of_first_operand =
+ GetVectorComponentCount(first_operand.instruction->type_id());
+ uint32_t size_of_second_operand =
+ GetVectorComponentCount(second_operand.instruction->type_id());
for (uint32_t in_op = 2; in_op < current_item.instruction->NumInOperands();
++in_op) {
@@ -187,7 +191,7 @@ void VectorDCE::MarkVectorShuffleUsesAsLive(
if (current_item.components.Get(in_op - 2)) {
if (index < size_of_first_operand) {
first_operand.components.Set(index);
- } else {
+ } else if (index - size_of_first_operand < size_of_second_operand) {
second_operand.components.Set(index - size_of_first_operand);
}
}
@@ -202,7 +206,6 @@ void VectorDCE::MarkCompositeContructUsesAsLive(
VectorDCE::LiveComponentMap* live_components,
std::vector<VectorDCE::WorkListItem>* work_list) {
analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr();
- analysis::TypeManager* type_mgr = context()->get_type_mgr();
uint32_t current_component = 0;
Instruction* current_inst = work_item.instruction;
@@ -223,8 +226,7 @@ void VectorDCE::MarkCompositeContructUsesAsLive(
assert(HasVectorResult(op_inst));
WorkListItem new_work_item;
new_work_item.instruction = op_inst;
- uint32_t op_vector_size =
- type_mgr->GetType(op_inst->type_id())->AsVector()->element_count();
+ uint32_t op_vector_size = GetVectorComponentCount(op_inst->type_id());
for (uint32_t op_vector_idx = 0; op_vector_idx < op_vector_size;
op_vector_idx++, current_component++) {
@@ -297,6 +299,18 @@ bool VectorDCE::HasScalarResult(const Instruction* inst) const {
}
}
+uint32_t VectorDCE::GetVectorComponentCount(uint32_t type_id) {
+ assert(type_id != 0 &&
+ "Trying to get the vector element count, but the type id is 0");
+ analysis::TypeManager* type_mgr = context()->get_type_mgr();
+ const analysis::Type* type = type_mgr->GetType(type_id);
+ const analysis::Vector* vector_type = type->AsVector();
+ assert(
+ vector_type &&
+ "Trying to get the vector element count, but the type is not a vector");
+ return vector_type->element_count();
+}
+
bool VectorDCE::RewriteInstructions(
Function* function, const VectorDCE::LiveComponentMap& live_components) {
bool modified = false;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.h
index 0df9aee13d7..4d30b926b8f 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/opt/vector_dce.h
@@ -94,12 +94,15 @@ class VectorDCE : public MemPass {
// Returns true if the result of |inst| is a vector or a scalar.
bool HasVectorOrScalarResult(const Instruction* inst) const;
- // Returns true if the result of |inst| is a scalar.
+ // Returns true if the result of |inst| is a vector.
bool HasVectorResult(const Instruction* inst) const;
- // Returns true if the result of |inst| is a vector.
+ // Returns true if the result of |inst| is a scalar.
bool HasScalarResult(const Instruction* inst) const;
+ // Returns the number of elements in the vector type with id |type_id|.
+ uint32_t GetVectorComponentCount(uint32_t type_id);
+
// Adds |work_item| to |work_list| if it is not already live according to
// |live_components|. |live_components| is updated to indicate that
// |work_item| is now live.
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.cpp
index 2716cca9be1..e5b1eece0dd 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.cpp
@@ -120,3 +120,8 @@ void spvValidatorOptionsSetSkipBlockLayout(spv_validator_options options,
bool val) {
options->skip_block_layout = val;
}
+
+void spvValidatorOptionsSetAllowLocalSizeId(spv_validator_options options,
+ bool val) {
+ options->allow_localsizeid = val;
+}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.h
index baaa5359e97..a357c031b54 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/spirv_validator_options.h
@@ -47,6 +47,7 @@ struct spv_validator_options_t {
scalar_block_layout(false),
workgroup_scalar_block_layout(false),
skip_block_layout(false),
+ allow_localsizeid(false),
before_hlsl_legalization(false) {}
validator_universal_limits_t universal_limits_;
@@ -57,6 +58,7 @@ struct spv_validator_options_t {
bool scalar_block_layout;
bool workgroup_scalar_block_layout;
bool skip_block_layout;
+ bool allow_localsizeid;
bool before_hlsl_legalization;
};
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/util/hex_float.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/util/hex_float.h
index cfc40fa6899..be28eae3ae3 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/util/hex_float.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/util/hex_float.h
@@ -1005,6 +1005,9 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
is.get();
next_char = is.peek();
}
+
+ // Finished reading the part preceding any '.' or 'p'.
+
bits_written = false;
while (seen_dot && !seen_p) {
// Handle only fractional parts now.
@@ -1037,11 +1040,16 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
next_char = is.peek();
}
+ // Finished reading the part preceding 'p'.
+ // In hex floats syntax, the binary exponent is required.
+
bool seen_sign = false;
int8_t exponent_sign = 1;
+ bool seen_written_exponent_digits = false;
int_type written_exponent = 0;
while (true) {
- if ((next_char == '-' || next_char == '+')) {
+ if (!seen_written_exponent_digits &&
+ (next_char == '-' || next_char == '+')) {
if (seen_sign) {
is.setstate(std::ios::failbit);
return is;
@@ -1049,6 +1057,7 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
seen_sign = true;
exponent_sign = (next_char == '-') ? -1 : 1;
} else if (::isdigit(next_char)) {
+ seen_written_exponent_digits = true;
// Hex-floats express their exponent as decimal.
written_exponent = static_cast<int_type>(written_exponent * 10);
written_exponent =
@@ -1059,6 +1068,11 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
is.get();
next_char = is.peek();
}
+ if (!seen_written_exponent_digits) {
+ // Binary exponent had no digits.
+ is.setstate(std::ios::failbit);
+ return is;
+ }
written_exponent = static_cast<int_type>(written_exponent * exponent_sign);
exponent = static_cast<int_type>(exponent + written_exponent);
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/construct.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/construct.cpp
index 53008690623..251e2bbaee7 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/construct.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/construct.cpp
@@ -181,8 +181,9 @@ bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const {
for (auto& use : block->label()->uses()) {
if ((use.first->opcode() == SpvOpLoopMerge ||
use.first->opcode() == SpvOpSelectionMerge) &&
- use.second == 1)
+ use.second == 1 && use.first->block()->dominates(*block)) {
return use.first->block();
+ }
}
return block->immediate_dominator();
};
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/function.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/function.cpp
index 249c8664fed..9ad68e86727 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/function.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/function.cpp
@@ -308,6 +308,9 @@ int Function::GetBlockDepth(BasicBlock* bb) {
if (block_depth_.find(bb) != block_depth_.end()) {
return block_depth_[bb];
}
+ // Avoid recursion. Something is wrong if the same block is encountered
+ // multiple times.
+ block_depth_[bb] = 0;
BasicBlock* bb_dom = bb->immediate_dominator();
if (!bb_dom || bb == bb_dom) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp
index 64655b0dc7b..8e6c373ea91 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp
@@ -60,7 +60,10 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) {
// TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need
// to discuss the location of DebugScope, DebugNoScope, DebugDeclare,
// and DebugValue.
- if (!spvExtInstIsDebugInfo(inst.ext_inst_type())) {
+ // NOTE: This does not apply to the non-semantic vulkan debug info.
+ if (!spvExtInstIsDebugInfo(inst.ext_inst_type()) ||
+ inst.ext_inst_type() ==
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
adjacency_status = PHI_AND_VAR_INVALID;
}
break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_atomics.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_atomics.cpp
index da023b80c58..cfa15d9f729 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_atomics.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_atomics.cpp
@@ -184,7 +184,7 @@ spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
}
// Can't use result_type because OpAtomicStore doesn't have a result
- if (_.GetBitWidth(data_type) == 64 && _.IsIntScalarType(data_type) &&
+ if ( _.IsIntScalarType(data_type) &&_.GetBitWidth(data_type) == 64 &&
!_.HasCapability(SpvCapabilityInt64Atomics)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< spvOpcodeString(opcode)
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp
index 3c9df9fc2d9..a6e624f7484 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp
@@ -2846,7 +2846,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference(
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
- << " to be used only with GLCompute execution model. "
+ << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
@@ -2928,7 +2928,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference(
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
- << " to be used only with GLCompute execution model. "
+ << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
@@ -3070,14 +3070,16 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference(
const Instruction& referenced_from_inst) {
if (spvIsVulkanEnv(_.context()->target_env)) {
for (const SpvExecutionModel execution_model : execution_models_) {
- if (execution_model != SpvExecutionModelGLCompute) {
+ if (execution_model != SpvExecutionModelGLCompute &&
+ execution_model != SpvExecutionModelTaskNV &&
+ execution_model != SpvExecutionModelMeshNV) {
return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
<< _.VkErrorID(4425)
<< spvLogStringForEnv(_.context()->target_env)
<< " spec allows BuiltIn "
<< _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
decoration.params()[0])
- << " to be used only with GLCompute execution model. "
+ << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
<< GetReferenceDesc(decoration, built_in_inst, referenced_inst,
referenced_from_inst, execution_model);
}
@@ -4190,6 +4192,7 @@ spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition(
case SpvBuiltInMeshViewIndicesNV:
case SpvBuiltInBaryCoordNV:
case SpvBuiltInBaryCoordNoPerspNV:
+ case SpvBuiltInCurrentRayTimeNV:
// No validation rules (for the moment).
break;
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_cfg.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_cfg.cpp
index 36f632a8d86..f08ab19f53e 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_cfg.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_cfg.cpp
@@ -199,6 +199,18 @@ spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) {
// At least two operands (selector, default), any more than that are
// literal/target.
+ const auto sel_type_id = _.GetOperandTypeId(inst, 0);
+ if (!_.IsIntScalarType(sel_type_id)) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Selector type must be OpTypeInt";
+ }
+
+ const auto default_label = _.FindDef(inst->GetOperandAs<uint32_t>(1));
+ if (default_label->opcode() != SpvOpLabel) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Default must be an OpLabel instruction";
+ }
+
// target operands must be OpLabel
for (size_t i = 2; i < num_operands; i += 2) {
// literal, id
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp
index 615adc72a05..8e4c42e4119 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp
@@ -129,18 +129,28 @@ std::vector<uint32_t> getStructMembers(uint32_t struct_id, SpvOp type,
// Returns whether the given structure is missing Offset decoration for any
// member. Handles also nested structures.
bool isMissingOffsetInStruct(uint32_t struct_id, ValidationState_t& vstate) {
- std::vector<bool> hasOffset(getStructMembers(struct_id, vstate).size(),
- false);
- // Check offsets of member decorations
- for (auto& decoration : vstate.id_decorations(struct_id)) {
- if (SpvDecorationOffset == decoration.dec_type() &&
- Decoration::kInvalidMember != decoration.struct_member_index()) {
- hasOffset[decoration.struct_member_index()] = true;
+ const auto* inst = vstate.FindDef(struct_id);
+ std::vector<bool> hasOffset;
+ std::vector<uint32_t> struct_members;
+ if (inst->opcode() == SpvOpTypeStruct) {
+ // Check offsets of member decorations.
+ struct_members = getStructMembers(struct_id, vstate);
+ hasOffset.resize(struct_members.size(), false);
+
+ for (auto& decoration : vstate.id_decorations(struct_id)) {
+ if (SpvDecorationOffset == decoration.dec_type() &&
+ Decoration::kInvalidMember != decoration.struct_member_index()) {
+ hasOffset[decoration.struct_member_index()] = true;
+ }
}
+ } else if (inst->opcode() == SpvOpTypeArray ||
+ inst->opcode() == SpvOpTypeRuntimeArray) {
+ hasOffset.resize(1, true);
+ struct_members.push_back(inst->GetOperandAs<uint32_t>(1u));
}
- // Check also nested structures
+ // Look through nested structs (which may be in an array).
bool nestedStructsMissingOffset = false;
- for (auto id : getStructMembers(struct_id, SpvOpTypeStruct, vstate)) {
+ for (auto id : struct_members) {
if (isMissingOffsetInStruct(id, vstate)) {
nestedStructsMissingOffset = true;
break;
@@ -506,12 +516,10 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str,
return recursive_status;
// Check matrix stride.
if (SpvOpTypeMatrix == opcode) {
- for (auto& decoration : vstate.id_decorations(id)) {
- if (SpvDecorationMatrixStride == decoration.dec_type() &&
- !IsAlignedTo(decoration.params()[0], alignment))
- return fail(memberIdx)
- << "is a matrix with stride " << decoration.params()[0]
- << " not satisfying alignment to " << alignment;
+ const auto stride = constraint.matrix_stride;
+ if (!IsAlignedTo(stride, alignment)) {
+ return fail(memberIdx) << "is a matrix with stride " << stride
+ << " not satisfying alignment to " << alignment;
}
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp
index 1f7b95633f8..dccbe14908d 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp
@@ -20,7 +20,9 @@
#include "spirv/unified1/NonSemanticClspvReflection.h"
+#include "NonSemanticShaderDebugInfo100.h"
#include "OpenCLDebugInfo100.h"
+#include "source/common_debug_info.h"
#include "source/diagnostic.h"
#include "source/enum_string_mapping.h"
#include "source/extensions.h"
@@ -45,6 +47,34 @@ uint32_t GetSizeTBitWidth(const ValidationState_t& _) {
return 0;
}
+bool IsIntScalar(ValidationState_t& _, uint32_t id, bool must_len32,
+ bool must_unsigned) {
+ auto type = _.FindDef(id);
+ if (!type || type->opcode() != SpvOpTypeInt) {
+ return false;
+ }
+
+ if (must_len32 && type->GetOperandAs<uint32_t>(1) != 32) {
+ return false;
+ }
+
+ return !must_unsigned || type->GetOperandAs<uint32_t>(2) == 0;
+}
+
+bool IsUint32Constant(ValidationState_t& _, uint32_t id) {
+ auto inst = _.FindDef(id);
+ if (!inst || inst->opcode() != SpvOpConstant) {
+ return false;
+ }
+
+ return IsIntScalar(_, inst->type_id(), true, true);
+}
+
+uint32_t GetUint32Constant(ValidationState_t& _, uint32_t id) {
+ auto inst = _.FindDef(id);
+ return inst->word(3);
+}
+
// Check that the operand of a debug info instruction |inst| at |word_index|
// is a result id of an instruction with |expected_opcode|.
spv_result_t ValidateOperandForDebugInfo(
@@ -68,6 +98,22 @@ spv_result_t ValidateOperandForDebugInfo(
return SPV_SUCCESS;
}
+// For NonSemantic.Shader.DebugInfo.100 check that the operand of a debug info
+// instruction |inst| at |word_index| is a result id of a 32-bit integer
+// OpConstant instruction. For OpenCL.DebugInfo.100 the parameter is a literal
+// word so cannot be validated.
+spv_result_t ValidateUint32ConstantOperandForDebugInfo(
+ ValidationState_t& _, const std::string& operand_name,
+ const Instruction* inst, uint32_t word_index,
+ const std::function<std::string()>& ext_inst_name) {
+ if (!IsUint32Constant(_, inst->word(word_index))) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": expected operand " << operand_name
+ << " must be a result id of 32-bit unsigned OpConstant";
+ }
+ return SPV_SUCCESS;
+}
+
#define CHECK_OPERAND(NAME, opcode, index) \
do { \
auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
@@ -75,18 +121,27 @@ spv_result_t ValidateOperandForDebugInfo(
if (result != SPV_SUCCESS) return result; \
} while (0)
+#define CHECK_CONST_UINT_OPERAND(NAME, index) \
+ if (vulkanDebugInfo) { \
+ auto result = ValidateUint32ConstantOperandForDebugInfo( \
+ _, NAME, inst, index, ext_inst_name); \
+ if (result != SPV_SUCCESS) return result; \
+ }
+
// True if the operand of a debug info instruction |inst| at |word_index|
// satisifies |expectation| that is given as a function. Otherwise,
// returns false.
bool DoesDebugInfoOperandMatchExpectation(
const ValidationState_t& _,
- const std::function<bool(OpenCLDebugInfo100Instructions)>& expectation,
+ const std::function<bool(CommonDebugInfoInstructions)>& expectation,
const Instruction* inst, uint32_t word_index) {
if (inst->words().size() <= word_index) return false;
auto* debug_inst = _.FindDef(inst->word(word_index));
if (debug_inst->opcode() != SpvOpExtInst ||
- debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
- !expectation(OpenCLDebugInfo100Instructions(debug_inst->word(4)))) {
+ (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 &&
+ debug_inst->ext_inst_type() !=
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) ||
+ !expectation(CommonDebugInfoInstructions(debug_inst->word(4)))) {
return false;
}
return true;
@@ -97,20 +152,18 @@ bool DoesDebugInfoOperandMatchExpectation(
// is |expected_debug_inst|.
spv_result_t ValidateDebugInfoOperand(
ValidationState_t& _, const std::string& debug_inst_name,
- OpenCLDebugInfo100Instructions expected_debug_inst, const Instruction* inst,
+ CommonDebugInfoInstructions expected_debug_inst, const Instruction* inst,
uint32_t word_index, const std::function<std::string()>& ext_inst_name) {
- std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
- [expected_debug_inst](OpenCLDebugInfo100Instructions dbg_inst) {
+ std::function<bool(CommonDebugInfoInstructions)> expectation =
+ [expected_debug_inst](CommonDebugInfoInstructions dbg_inst) {
return dbg_inst == expected_debug_inst;
};
if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
return SPV_SUCCESS;
spv_ext_inst_desc desc = nullptr;
- _.grammar().lookupExtInst(SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
- expected_debug_inst, &desc);
- if (_.grammar().lookupExtInst(SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100,
- expected_debug_inst, &desc) != SPV_SUCCESS ||
+ if (_.grammar().lookupExtInst(inst->ext_inst_type(), expected_debug_inst,
+ &desc) != SPV_SUCCESS ||
!desc) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
@@ -134,9 +187,8 @@ spv_result_t ValidateDebugInfoOperand(
spv_result_t ValidateOperandBaseType(
ValidationState_t& _, const Instruction* inst, uint32_t word_index,
const std::function<std::string()>& ext_inst_name) {
- return ValidateDebugInfoOperand(_, "Base Type",
- OpenCLDebugInfo100DebugTypeBasic, inst,
- word_index, ext_inst_name);
+ return ValidateDebugInfoOperand(_, "Base Type", CommonDebugInfoDebugTypeBasic,
+ inst, word_index, ext_inst_name);
}
// Check that the operand of a debug info instruction |inst| at |word_index|
@@ -147,12 +199,12 @@ spv_result_t ValidateOperandLexicalScope(
ValidationState_t& _, const std::string& debug_inst_name,
const Instruction* inst, uint32_t word_index,
const std::function<std::string()>& ext_inst_name) {
- std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugCompilationUnit ||
- dbg_inst == OpenCLDebugInfo100DebugFunction ||
- dbg_inst == OpenCLDebugInfo100DebugLexicalBlock ||
- dbg_inst == OpenCLDebugInfo100DebugTypeComposite;
+ std::function<bool(CommonDebugInfoInstructions)> expectation =
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugCompilationUnit ||
+ dbg_inst == CommonDebugInfoDebugFunction ||
+ dbg_inst == CommonDebugInfoDebugLexicalBlock ||
+ dbg_inst == CommonDebugInfoDebugTypeComposite;
};
if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
return SPV_SUCCESS;
@@ -171,16 +223,15 @@ spv_result_t ValidateOperandDebugType(
const Instruction* inst, uint32_t word_index,
const std::function<std::string()>& ext_inst_name,
bool allow_template_param) {
- std::function<bool(OpenCLDebugInfo100Instructions)> expectation =
- [&allow_template_param](OpenCLDebugInfo100Instructions dbg_inst) {
+ std::function<bool(CommonDebugInfoInstructions)> expectation =
+ [&allow_template_param](CommonDebugInfoInstructions dbg_inst) {
if (allow_template_param &&
- (dbg_inst == OpenCLDebugInfo100DebugTypeTemplateParameter ||
- dbg_inst ==
- OpenCLDebugInfo100DebugTypeTemplateTemplateParameter)) {
+ (dbg_inst == CommonDebugInfoDebugTypeTemplateParameter ||
+ dbg_inst == CommonDebugInfoDebugTypeTemplateTemplateParameter)) {
return true;
}
- return OpenCLDebugInfo100DebugTypeBasic <= dbg_inst &&
- dbg_inst <= OpenCLDebugInfo100DebugTypeTemplate;
+ return CommonDebugInfoDebugTypeBasic <= dbg_inst &&
+ dbg_inst <= CommonDebugInfoDebugTypeTemplate;
};
if (DoesDebugInfoOperandMatchExpectation(_, expectation, inst, word_index))
return SPV_SUCCESS;
@@ -191,28 +242,6 @@ spv_result_t ValidateOperandDebugType(
<< " is not a valid debug type";
}
-bool IsUint32Constant(ValidationState_t& _, uint32_t id) {
- auto inst = _.FindDef(id);
- if (!inst || inst->opcode() != SpvOpConstant) {
- return false;
- }
-
- auto type = _.FindDef(inst->type_id());
- if (!type || type->opcode() != SpvOpTypeInt) {
- return false;
- }
-
- if (type->GetOperandAs<uint32_t>(1) != 32) {
- return false;
- }
-
- if (type->GetOperandAs<uint32_t>(2) != 0) {
- return false;
- }
-
- return true;
-}
-
spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _,
const Instruction* inst) {
const auto kernel_id = inst->GetOperandAs<uint32_t>(4);
@@ -667,18 +696,26 @@ bool IsDebugVariableWithIntScalarType(ValidationState_t& _,
const Instruction* inst,
uint32_t word_index) {
auto* dbg_int_scalar_var = _.FindDef(inst->word(word_index));
- if (OpenCLDebugInfo100Instructions(dbg_int_scalar_var->word(4)) ==
- OpenCLDebugInfo100DebugLocalVariable ||
- OpenCLDebugInfo100Instructions(dbg_int_scalar_var->word(4)) ==
- OpenCLDebugInfo100DebugGlobalVariable) {
+ if (CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) ==
+ CommonDebugInfoDebugLocalVariable ||
+ CommonDebugInfoInstructions(dbg_int_scalar_var->word(4)) ==
+ CommonDebugInfoDebugGlobalVariable) {
auto* dbg_type = _.FindDef(dbg_int_scalar_var->word(6));
- if (OpenCLDebugInfo100Instructions(dbg_type->word(4)) ==
- OpenCLDebugInfo100DebugTypeBasic &&
- (OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(dbg_type->word(7)) ==
- OpenCLDebugInfo100Signed ||
- OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(dbg_type->word(7)) ==
- OpenCLDebugInfo100Unsigned)) {
- return true;
+ if (CommonDebugInfoInstructions(dbg_type->word(4)) ==
+ CommonDebugInfoDebugTypeBasic) {
+ const spv_ext_inst_type_t ext_inst_type =
+ spv_ext_inst_type_t(inst->ext_inst_type());
+ const bool vulkanDebugInfo =
+ ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
+ uint32_t encoding = dbg_type->word(7);
+ if (!vulkanDebugInfo || IsUint32Constant(_, encoding)) {
+ auto ocl_encoding = OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
+ vulkanDebugInfo ? GetUint32Constant(_, encoding) : encoding);
+ if (ocl_encoding == OpenCLDebugInfo100Signed ||
+ ocl_encoding == OpenCLDebugInfo100Unsigned) {
+ return true;
+ }
+ }
}
}
return false;
@@ -2668,7 +2705,9 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
break;
}
}
- } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
+ } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
+ ext_inst_type ==
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
if (!_.IsVoidType(result_type)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
@@ -2676,447 +2715,552 @@ spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
<< "OpTypeVoid";
}
- auto num_words = inst->words().size();
+ const bool vulkanDebugInfo =
+ ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
- const OpenCLDebugInfo100Instructions ext_inst_key =
- OpenCLDebugInfo100Instructions(ext_inst_index);
- switch (ext_inst_key) {
- case OpenCLDebugInfo100DebugInfoNone:
- case OpenCLDebugInfo100DebugNoScope:
- case OpenCLDebugInfo100DebugOperation:
- // The binary parser validates the opcode for DebugInfoNone,
- // DebugNoScope, DebugOperation, and the literal values don't need
- // further checks.
- break;
- case OpenCLDebugInfo100DebugCompilationUnit: {
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- break;
- }
- case OpenCLDebugInfo100DebugSource: {
- CHECK_OPERAND("File", SpvOpString, 5);
- if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6);
- break;
- }
- case OpenCLDebugInfo100DebugTypeBasic: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- CHECK_OPERAND("Size", SpvOpConstant, 6);
- // "Encoding" param is already validated by the binary parsing stage.
- break;
- }
- case OpenCLDebugInfo100DebugTypePointer:
- case OpenCLDebugInfo100DebugTypeQualifier: {
- auto validate_base_type =
- ValidateOperandBaseType(_, inst, 5, ext_inst_name);
- if (validate_base_type != SPV_SUCCESS) return validate_base_type;
- break;
- }
- case OpenCLDebugInfo100DebugTypeVector: {
- auto validate_base_type =
- ValidateOperandBaseType(_, inst, 5, ext_inst_name);
- if (validate_base_type != SPV_SUCCESS) return validate_base_type;
+ auto num_words = inst->words().size();
- uint32_t component_count = inst->word(6);
- if (!component_count || component_count > 4) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": Component Count must be positive "
- << "integer less than or equal to 4";
- }
- break;
- }
- case OpenCLDebugInfo100DebugTypeArray: {
- auto validate_base_type = ValidateOperandDebugType(
- _, "Base Type", inst, 5, ext_inst_name, false);
- if (validate_base_type != SPV_SUCCESS) return validate_base_type;
- for (uint32_t i = 6; i < num_words; ++i) {
- bool invalid = false;
- auto* component_count = _.FindDef(inst->word(i));
- if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
- // TODO: We need a spec discussion for the bindless array.
- if (!component_count->word(3)) {
- invalid = true;
+ // Handle any non-common OpenCL insts, then common
+ if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
+ OpenCLDebugInfo100Instructions(ext_inst_index) !=
+ OpenCLDebugInfo100DebugModuleINTEL) {
+ const CommonDebugInfoInstructions ext_inst_key =
+ CommonDebugInfoInstructions(ext_inst_index);
+ switch (ext_inst_key) {
+ case CommonDebugInfoDebugInfoNone:
+ case CommonDebugInfoDebugNoScope:
+ break;
+ // The binary parser validates the opcode for DebugInfoNone,
+ // DebugNoScope, DebugOperation. We just check the parameters to
+ // DebugOperation are properly constants for vulkan debug info.
+ case CommonDebugInfoDebugOperation: {
+ CHECK_CONST_UINT_OPERAND("Operation", 5);
+ for (uint32_t i = 6; i < num_words; ++i) {
+ CHECK_CONST_UINT_OPERAND("Operand", i);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugCompilationUnit: {
+ CHECK_CONST_UINT_OPERAND("Version", 5);
+ CHECK_CONST_UINT_OPERAND("DWARF Version", 6);
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Language", 8);
+ break;
+ }
+ case CommonDebugInfoDebugSource: {
+ CHECK_OPERAND("File", SpvOpString, 5);
+ if (num_words == 7) CHECK_OPERAND("Text", SpvOpString, 6);
+ break;
+ }
+ case CommonDebugInfoDebugTypeBasic: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ CHECK_OPERAND("Size", SpvOpConstant, 6);
+ CHECK_CONST_UINT_OPERAND("Encoding", 7);
+ break;
+ }
+ case CommonDebugInfoDebugTypePointer: {
+ auto validate_base_type =
+ ValidateOperandBaseType(_, inst, 5, ext_inst_name);
+ 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);
+ if (validate_base_type != SPV_SUCCESS) return validate_base_type;
+ CHECK_CONST_UINT_OPERAND("Type Qualifier", 6);
+ break;
+ }
+ case CommonDebugInfoDebugTypeVector: {
+ auto validate_base_type =
+ ValidateOperandBaseType(_, inst, 5, ext_inst_name);
+ if (validate_base_type != SPV_SUCCESS) return validate_base_type;
+
+ CHECK_CONST_UINT_OPERAND("Component Count", 6);
+ uint32_t component_count = inst->word(6);
+ if (vulkanDebugInfo) {
+ uint64_t const_val;
+ if (!_.GetConstantValUint64(component_count, &const_val)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name()
+ << ": Component Count must be 32-bit integer OpConstant";
}
- } else if (component_count->words().size() > 6 &&
- (OpenCLDebugInfo100Instructions(component_count->word(
- 4)) == OpenCLDebugInfo100DebugLocalVariable ||
- OpenCLDebugInfo100Instructions(component_count->word(
- 4)) == OpenCLDebugInfo100DebugGlobalVariable)) {
- auto* component_count_type = _.FindDef(component_count->word(6));
- if (component_count_type->words().size() > 7) {
- if (OpenCLDebugInfo100Instructions(component_count_type->word(
- 4)) != OpenCLDebugInfo100DebugTypeBasic ||
- OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
- component_count_type->word(7)) !=
- OpenCLDebugInfo100Unsigned) {
+ component_count = const_val & 0xffffffff;
+ }
+
+ if (!component_count || component_count > 4) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": Component Count must be positive "
+ << "integer less than or equal to 4";
+ }
+ break;
+ }
+ case CommonDebugInfoDebugTypeArray: {
+ auto validate_base_type = ValidateOperandDebugType(
+ _, "Base Type", inst, 5, ext_inst_name, false);
+ if (validate_base_type != SPV_SUCCESS) return validate_base_type;
+ for (uint32_t i = 6; i < num_words; ++i) {
+ bool invalid = false;
+ auto* component_count = _.FindDef(inst->word(i));
+ if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
+ // TODO: We need a spec discussion for the bindless array.
+ if (!component_count->word(3)) {
invalid = true;
- } else {
- // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
- // must have Unsigned encoding and 32 or 64 as its size in bits.
- Instruction* size_in_bits =
- _.FindDef(component_count_type->word(6));
- if (!_.IsIntScalarType(size_in_bits->type_id()) ||
- (size_in_bits->word(3) != 32 &&
- size_in_bits->word(3) != 64)) {
+ }
+ } else if (component_count->words().size() > 6 &&
+ (CommonDebugInfoInstructions(component_count->word(4)) ==
+ CommonDebugInfoDebugLocalVariable ||
+ CommonDebugInfoInstructions(component_count->word(4)) ==
+ CommonDebugInfoDebugGlobalVariable)) {
+ auto* component_count_type = _.FindDef(component_count->word(6));
+ if (component_count_type->words().size() > 7) {
+ uint32_t encoding = component_count_type->word(7);
+ if (CommonDebugInfoInstructions(component_count_type->word(
+ 4)) != CommonDebugInfoDebugTypeBasic ||
+ (vulkanDebugInfo && !IsUint32Constant(_, encoding)) ||
+ OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
+ vulkanDebugInfo
+ ? GetUint32Constant(_, encoding)
+ : encoding) != OpenCLDebugInfo100Unsigned) {
invalid = true;
+ } else {
+ // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
+ // must have Unsigned encoding and 32 or 64 as its size in
+ // bits.
+ Instruction* size_in_bits =
+ _.FindDef(component_count_type->word(6));
+ if (!_.IsIntScalarType(size_in_bits->type_id()) ||
+ (size_in_bits->word(3) != 32 &&
+ size_in_bits->word(3) != 64)) {
+ invalid = true;
+ }
}
+ } else {
+ invalid = true;
}
} else {
invalid = true;
}
- } else {
- invalid = true;
+ if (invalid) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": Component Count must be "
+ << "OpConstant with a 32- or 64-bits integer scalar type "
+ "or "
+ << "DebugGlobalVariable or DebugLocalVariable with a 32- "
+ "or "
+ << "64-bits unsigned integer scalar type";
+ }
}
- if (invalid) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": Component Count must be "
- << "OpConstant with a 32- or 64-bits integer scalar type or "
- << "DebugGlobalVariable or DebugLocalVariable with a 32- or "
- << "64-bits unsigned integer scalar type";
+ break;
+ }
+ case CommonDebugInfoDebugTypedef: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ auto validate_base_type =
+ ValidateOperandBaseType(_, inst, 6, ext_inst_name);
+ if (validate_base_type != SPV_SUCCESS) return validate_base_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ break;
+ }
+ case CommonDebugInfoDebugTypeFunction: {
+ CHECK_CONST_UINT_OPERAND("Flags", 5);
+ auto* return_type = _.FindDef(inst->word(6));
+ // TODO: We need a spec discussion that we have to allow return and
+ // parameter types of a DebugTypeFunction to have template parameter.
+ if (return_type->opcode() != SpvOpTypeVoid) {
+ auto validate_return = ValidateOperandDebugType(
+ _, "Return Type", inst, 6, ext_inst_name, true);
+ if (validate_return != SPV_SUCCESS) return validate_return;
}
+ for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
+ auto validate_param = ValidateOperandDebugType(
+ _, "Parameter Types", inst, word_index, ext_inst_name, true);
+ if (validate_param != SPV_SUCCESS) return validate_param;
+ }
+ break;
}
- break;
- }
- case OpenCLDebugInfo100DebugTypedef: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- auto validate_base_type =
- ValidateOperandBaseType(_, inst, 6, ext_inst_name);
- if (validate_base_type != SPV_SUCCESS) return validate_base_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- break;
- }
- case OpenCLDebugInfo100DebugTypeFunction: {
- auto* return_type = _.FindDef(inst->word(6));
- // TODO: We need a spec discussion that we have to allow return and
- // parameter types of a DebugTypeFunction to have template parameter.
- if (return_type->opcode() != SpvOpTypeVoid) {
- auto validate_return = ValidateOperandDebugType(
- _, "Return Type", inst, 6, ext_inst_name, true);
- if (validate_return != SPV_SUCCESS) return validate_return;
- }
- for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
- auto validate_param = ValidateOperandDebugType(
- _, "Parameter Types", inst, word_index, ext_inst_name, true);
- if (validate_param != SPV_SUCCESS) return validate_param;
- }
- break;
- }
- case OpenCLDebugInfo100DebugTypeEnum: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
- },
- inst, 6)) {
- auto validate_underlying_type = ValidateOperandDebugType(
- _, "Underlying Types", inst, 6, ext_inst_name, false);
- if (validate_underlying_type != SPV_SUCCESS)
- return validate_underlying_type;
- }
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- CHECK_OPERAND("Size", SpvOpConstant, 11);
- auto* size = _.FindDef(inst->word(11));
- if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": expected operand Size is a "
- << "positive integer";
- }
- for (uint32_t word_index = 13; word_index + 1 < num_words;
- word_index += 2) {
- CHECK_OPERAND("Value", SpvOpConstant, word_index);
- CHECK_OPERAND("Name", SpvOpString, word_index + 1);
- }
- break;
- }
- case OpenCLDebugInfo100DebugTypeComposite: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- CHECK_OPERAND("Linkage Name", SpvOpString, 11);
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
- },
- inst, 12)) {
- CHECK_OPERAND("Size", SpvOpConstant, 12);
- }
- for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
+ case CommonDebugInfoDebugTypeEnum: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
if (!DoesDebugInfoOperandMatchExpectation(
_,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugTypeMember ||
- dbg_inst == OpenCLDebugInfo100DebugFunction ||
- dbg_inst == OpenCLDebugInfo100DebugTypeInheritance;
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugInfoNone;
},
- inst, word_index)) {
+ inst, 6)) {
+ auto validate_underlying_type = ValidateOperandDebugType(
+ _, "Underlying Types", inst, 6, ext_inst_name, false);
+ if (validate_underlying_type != SPV_SUCCESS)
+ return validate_underlying_type;
+ }
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ CHECK_OPERAND("Size", SpvOpConstant, 11);
+ auto* size = _.FindDef(inst->word(11));
+ if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": "
- << "expected operand Members "
- << "must be DebugTypeMember, DebugFunction, or "
- "DebugTypeInheritance";
+ << ext_inst_name() << ": expected operand Size is a "
+ << "positive integer";
}
- }
- break;
- }
- case OpenCLDebugInfo100DebugTypeMember: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- // TODO: We need a spec discussion that we have to allow member types
- // to have template parameter.
- auto validate_type =
- ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
- if (validate_type != SPV_SUCCESS) return validate_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 10);
- CHECK_OPERAND("Offset", SpvOpConstant, 11);
- CHECK_OPERAND("Size", SpvOpConstant, 12);
- if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14);
- break;
- }
- case OpenCLDebugInfo100DebugTypeInheritance: {
- CHECK_DEBUG_OPERAND("Child", OpenCLDebugInfo100DebugTypeComposite, 5);
- auto* debug_inst = _.FindDef(inst->word(5));
- auto composite_type =
- OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
- if (composite_type != OpenCLDebugInfo100Class &&
- composite_type != OpenCLDebugInfo100Structure) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": "
- << "expected operand Child must be class or struct debug type";
- }
- CHECK_DEBUG_OPERAND("Parent", OpenCLDebugInfo100DebugTypeComposite, 6);
- debug_inst = _.FindDef(inst->word(6));
- composite_type =
- OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
- if (composite_type != OpenCLDebugInfo100Class &&
- composite_type != OpenCLDebugInfo100Structure) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": "
- << "expected operand Parent must be class or struct debug "
- "type";
- }
- CHECK_OPERAND("Offset", SpvOpConstant, 7);
- CHECK_OPERAND("Size", SpvOpConstant, 8);
- break;
- }
- case OpenCLDebugInfo100DebugFunction: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- auto validate_type =
- ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
- if (validate_type != SPV_SUCCESS) return validate_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- CHECK_OPERAND("Linkage Name", SpvOpString, 11);
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
- },
- inst, 14)) {
- CHECK_OPERAND("Function", SpvOpFunction, 14);
- }
- if (num_words == 16) {
- CHECK_DEBUG_OPERAND("Declaration",
- OpenCLDebugInfo100DebugFunctionDeclaration, 15);
- }
- break;
- }
- case OpenCLDebugInfo100DebugFunctionDeclaration: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- auto validate_type =
- ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
- if (validate_type != SPV_SUCCESS) return validate_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- CHECK_OPERAND("Linkage Name", SpvOpString, 11);
- break;
- }
- case OpenCLDebugInfo100DebugLexicalBlock: {
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 5);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9);
- break;
- }
- case OpenCLDebugInfo100DebugScope: {
- auto validate_scope =
- ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
- if (validate_scope != SPV_SUCCESS) return validate_scope;
- if (num_words == 7) {
- CHECK_DEBUG_OPERAND("Inlined At", OpenCLDebugInfo100DebugInlinedAt,
- 6);
- }
- break;
- }
- case OpenCLDebugInfo100DebugLocalVariable: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- // TODO: We need a spec discussion that we have to allow local variable
- // types to have template parameter.
- auto validate_type =
- ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
- if (validate_type != SPV_SUCCESS) return validate_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_parent =
- ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
- if (validate_parent != SPV_SUCCESS) return validate_parent;
- break;
- }
- case OpenCLDebugInfo100DebugDeclare: {
- CHECK_DEBUG_OPERAND("Local Variable",
- OpenCLDebugInfo100DebugLocalVariable, 5);
- auto* operand = _.FindDef(inst->word(6));
- if (operand->opcode() != SpvOpVariable &&
- operand->opcode() != SpvOpFunctionParameter) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": "
- << "expected operand Variable must be a result id of "
- "OpVariable or OpFunctionParameter";
- }
-
- CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
- break;
- }
- case OpenCLDebugInfo100DebugExpression: {
- for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
- CHECK_DEBUG_OPERAND("Operation", OpenCLDebugInfo100DebugOperation,
- word_index);
- }
- break;
- }
- case OpenCLDebugInfo100DebugTypeTemplate: {
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugTypeComposite ||
- dbg_inst == OpenCLDebugInfo100DebugFunction;
- },
- inst, 5)) {
- return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": "
- << "expected operand Target must be DebugTypeComposite "
- << "or DebugFunction";
- }
- for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
+ CHECK_CONST_UINT_OPERAND("Flags", 12);
+ for (uint32_t word_index = 13; word_index + 1 < num_words;
+ word_index += 2) {
+ CHECK_OPERAND("Value", SpvOpConstant, word_index);
+ CHECK_OPERAND("Name", SpvOpString, word_index + 1);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugTypeComposite: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ CHECK_OPERAND("Linkage Name", SpvOpString, 11);
if (!DoesDebugInfoOperandMatchExpectation(
_,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst ==
- OpenCLDebugInfo100DebugTypeTemplateParameter ||
- dbg_inst ==
- OpenCLDebugInfo100DebugTypeTemplateTemplateParameter;
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugInfoNone;
},
- inst, word_index)) {
+ inst, 12)) {
+ CHECK_OPERAND("Size", SpvOpConstant, 12);
+ }
+ CHECK_CONST_UINT_OPERAND("Flags", 13);
+ for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugTypeMember ||
+ dbg_inst == CommonDebugInfoDebugFunction ||
+ dbg_inst == CommonDebugInfoDebugTypeInheritance;
+ },
+ inst, word_index)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": "
+ << "expected operand Members "
+ << "must be DebugTypeMember, DebugFunction, or "
+ "DebugTypeInheritance";
+ }
+ }
+ break;
+ }
+ case CommonDebugInfoDebugTypeMember: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ // TODO: We need a spec discussion that we have to allow member types
+ // to have template parameter.
+ auto validate_type =
+ ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
+ if (validate_type != SPV_SUCCESS) return validate_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ // NonSemantic.Shader.DebugInfo doesn't have the Parent operand
+ if (vulkanDebugInfo) {
+ CHECK_OPERAND("Offset", SpvOpConstant, 10);
+ CHECK_OPERAND("Size", SpvOpConstant, 11);
+ CHECK_CONST_UINT_OPERAND("Flags", 12);
+ if (num_words == 14) CHECK_OPERAND("Value", SpvOpConstant, 13);
+ } else {
+ CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite,
+ 10);
+ CHECK_OPERAND("Offset", SpvOpConstant, 11);
+ CHECK_OPERAND("Size", SpvOpConstant, 12);
+ CHECK_CONST_UINT_OPERAND("Flags", 13);
+ if (num_words == 15) CHECK_OPERAND("Value", SpvOpConstant, 14);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugTypeInheritance: {
+ CHECK_DEBUG_OPERAND("Child", CommonDebugInfoDebugTypeComposite, 5);
+ auto* debug_inst = _.FindDef(inst->word(5));
+ auto composite_type =
+ OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
+ if (composite_type != OpenCLDebugInfo100Class &&
+ composite_type != OpenCLDebugInfo100Structure) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": "
+ << "expected operand Child must be class or struct debug "
+ "type";
+ }
+ CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 6);
+ debug_inst = _.FindDef(inst->word(6));
+ composite_type =
+ OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
+ if (composite_type != OpenCLDebugInfo100Class &&
+ composite_type != OpenCLDebugInfo100Structure) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
- << "expected operand Parameters must be "
- << "DebugTypeTemplateParameter or "
- << "DebugTypeTemplateTemplateParameter";
+ << "expected operand Parent must be class or struct debug "
+ "type";
}
+ CHECK_OPERAND("Offset", SpvOpConstant, 7);
+ CHECK_OPERAND("Size", SpvOpConstant, 8);
+ CHECK_CONST_UINT_OPERAND("Flags", 9);
+ break;
+ }
+ case CommonDebugInfoDebugFunction: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
+ ext_inst_name, false);
+ if (validate_type != SPV_SUCCESS) return validate_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ CHECK_OPERAND("Linkage Name", SpvOpString, 11);
+ CHECK_CONST_UINT_OPERAND("Flags", 12);
+ CHECK_CONST_UINT_OPERAND("Scope Line", 13);
+ // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the
+ // OpFunction
+ if (vulkanDebugInfo) {
+ if (num_words == 15) {
+ CHECK_DEBUG_OPERAND("Declaration",
+ CommonDebugInfoDebugFunctionDeclaration, 14);
+ }
+ } else {
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugInfoNone;
+ },
+ inst, 14)) {
+ CHECK_OPERAND("Function", SpvOpFunction, 14);
+ }
+ if (num_words == 16) {
+ CHECK_DEBUG_OPERAND("Declaration",
+ CommonDebugInfoDebugFunctionDeclaration, 15);
+ }
+ }
+ break;
+ }
+ case CommonDebugInfoDebugFunctionDeclaration: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
+ ext_inst_name, false);
+ if (validate_type != SPV_SUCCESS) return validate_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ CHECK_OPERAND("Linkage Name", SpvOpString, 11);
+ CHECK_CONST_UINT_OPERAND("Flags", 12);
+ break;
+ }
+ case CommonDebugInfoDebugLexicalBlock: {
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5);
+ CHECK_CONST_UINT_OPERAND("Line", 6);
+ CHECK_CONST_UINT_OPERAND("Column", 7);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ if (num_words == 10) CHECK_OPERAND("Name", SpvOpString, 9);
+ break;
+ }
+ case CommonDebugInfoDebugScope: {
+ auto validate_scope =
+ ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
+ if (validate_scope != SPV_SUCCESS) return validate_scope;
+ if (num_words == 7) {
+ CHECK_DEBUG_OPERAND("Inlined At", CommonDebugInfoDebugInlinedAt, 6);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugLocalVariable: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ // TODO: We need a spec discussion that we have to allow local
+ // variable types to have template parameter.
+ auto validate_type =
+ ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
+ if (validate_type != SPV_SUCCESS) return validate_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_parent =
+ ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
+ if (validate_parent != SPV_SUCCESS) return validate_parent;
+ CHECK_CONST_UINT_OPERAND("Flags", 11);
+ if (num_words == 13) {
+ CHECK_CONST_UINT_OPERAND("ArgNumber", 12);
+ }
+ break;
}
- break;
- }
- case OpenCLDebugInfo100DebugTypeTemplateParameter: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- auto validate_actual_type = ValidateOperandDebugType(
- _, "Actual Type", inst, 6, ext_inst_name, false);
- if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
- },
- inst, 7)) {
- CHECK_OPERAND("Value", SpvOpConstant, 7);
- }
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 8);
- break;
- }
- case OpenCLDebugInfo100DebugGlobalVariable: {
- CHECK_OPERAND("Name", SpvOpString, 5);
- auto validate_type =
- ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, false);
- if (validate_type != SPV_SUCCESS) return validate_type;
- CHECK_DEBUG_OPERAND("Source", OpenCLDebugInfo100DebugSource, 7);
- auto validate_scope =
- ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
- if (validate_scope != SPV_SUCCESS) return validate_scope;
- CHECK_OPERAND("Linkage Name", SpvOpString, 11);
- if (!DoesDebugInfoOperandMatchExpectation(
- _,
- [](OpenCLDebugInfo100Instructions dbg_inst) {
- return dbg_inst == OpenCLDebugInfo100DebugInfoNone;
- },
- inst, 12)) {
- auto* operand = _.FindDef(inst->word(12));
+ case CommonDebugInfoDebugDeclare: {
+ CHECK_DEBUG_OPERAND("Local Variable",
+ CommonDebugInfoDebugLocalVariable, 5);
+ auto* operand = _.FindDef(inst->word(6));
if (operand->opcode() != SpvOpVariable &&
- operand->opcode() != SpvOpConstant) {
+ operand->opcode() != SpvOpFunctionParameter) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< ext_inst_name() << ": "
<< "expected operand Variable must be a result id of "
- "OpVariable or OpConstant or DebugInfoNone";
+ "OpVariable or OpFunctionParameter";
}
+
+ CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
+
+ if (vulkanDebugInfo) {
+ for (uint32_t word_index = 8; word_index < num_words;
+ ++word_index) {
+ auto index_inst = _.FindDef(inst->word(word_index));
+ auto type_id = index_inst != nullptr ? index_inst->type_id() : 0;
+ if (type_id == 0 || !IsIntScalar(_, type_id, false, false))
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": "
+ << "expected index must be scalar integer";
+ }
+ }
+ break;
}
- if (num_words == 15) {
- CHECK_DEBUG_OPERAND("Static Member Declaration",
- OpenCLDebugInfo100DebugTypeMember, 14);
- }
- break;
- }
- case OpenCLDebugInfo100DebugInlinedAt: {
- auto validate_scope =
- ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
- if (validate_scope != SPV_SUCCESS) return validate_scope;
- if (num_words == 8) {
- CHECK_DEBUG_OPERAND("Inlined", OpenCLDebugInfo100DebugInlinedAt, 7);
+ case CommonDebugInfoDebugExpression: {
+ for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
+ CHECK_DEBUG_OPERAND("Operation", CommonDebugInfoDebugOperation,
+ word_index);
+ }
+ break;
}
- break;
- }
- case OpenCLDebugInfo100DebugValue: {
- CHECK_DEBUG_OPERAND("Local Variable",
- OpenCLDebugInfo100DebugLocalVariable, 5);
- CHECK_DEBUG_OPERAND("Expression", OpenCLDebugInfo100DebugExpression, 7);
-
- for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
- // TODO: The following code simply checks if it is a const int scalar
- // or a DebugLocalVariable or DebugGlobalVariable, but we have to
- // check it using the same validation for Indexes of OpAccessChain.
- if (!IsConstWithIntScalarType(_, inst, word_index) &&
- !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
+ case CommonDebugInfoDebugTypeTemplate: {
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugTypeComposite ||
+ dbg_inst == CommonDebugInfoDebugFunction;
+ },
+ inst, 5)) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
- << ext_inst_name() << ": expected operand Indexes is "
- << "OpConstant, DebugGlobalVariable, or "
- << "type is OpConstant with an integer scalar type";
+ << ext_inst_name() << ": "
+ << "expected operand Target must be DebugTypeComposite "
+ << "or DebugFunction";
+ }
+ for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst ==
+ CommonDebugInfoDebugTypeTemplateParameter ||
+ dbg_inst ==
+ CommonDebugInfoDebugTypeTemplateTemplateParameter;
+ },
+ inst, word_index)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": "
+ << "expected operand Parameters must be "
+ << "DebugTypeTemplateParameter or "
+ << "DebugTypeTemplateTemplateParameter";
+ }
}
+ break;
}
- break;
+ case CommonDebugInfoDebugTypeTemplateParameter: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ auto validate_actual_type = ValidateOperandDebugType(
+ _, "Actual Type", inst, 6, ext_inst_name, false);
+ if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugInfoNone;
+ },
+ inst, 7)) {
+ CHECK_OPERAND("Value", SpvOpConstant, 7);
+ }
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8);
+ CHECK_CONST_UINT_OPERAND("Line", 9);
+ CHECK_CONST_UINT_OPERAND("Column", 10);
+ break;
+ }
+ case CommonDebugInfoDebugGlobalVariable: {
+ CHECK_OPERAND("Name", SpvOpString, 5);
+ auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
+ ext_inst_name, false);
+ if (validate_type != SPV_SUCCESS) return validate_type;
+ CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
+ CHECK_CONST_UINT_OPERAND("Line", 8);
+ CHECK_CONST_UINT_OPERAND("Column", 9);
+ auto validate_scope =
+ ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
+ if (validate_scope != SPV_SUCCESS) return validate_scope;
+ CHECK_OPERAND("Linkage Name", SpvOpString, 11);
+ if (!DoesDebugInfoOperandMatchExpectation(
+ _,
+ [](CommonDebugInfoInstructions dbg_inst) {
+ return dbg_inst == CommonDebugInfoDebugInfoNone;
+ },
+ inst, 12)) {
+ auto* operand = _.FindDef(inst->word(12));
+ if (operand->opcode() != SpvOpVariable &&
+ operand->opcode() != SpvOpConstant) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": "
+ << "expected operand Variable must be a result id of "
+ "OpVariable or OpConstant or DebugInfoNone";
+ }
+ }
+ if (num_words == 15) {
+ CHECK_DEBUG_OPERAND("Static Member Declaration",
+ CommonDebugInfoDebugTypeMember, 14);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugInlinedAt: {
+ CHECK_CONST_UINT_OPERAND("Line", 5);
+ auto validate_scope =
+ ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
+ if (validate_scope != SPV_SUCCESS) return validate_scope;
+ if (num_words == 8) {
+ CHECK_DEBUG_OPERAND("Inlined", CommonDebugInfoDebugInlinedAt, 7);
+ }
+ break;
+ }
+ case CommonDebugInfoDebugValue: {
+ CHECK_DEBUG_OPERAND("Local Variable",
+ CommonDebugInfoDebugLocalVariable, 5);
+ CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
+
+ for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
+ // TODO: The following code simply checks if it is a const int
+ // scalar or a DebugLocalVariable or DebugGlobalVariable, but we
+ // have to check it using the same validation for Indexes of
+ // OpAccessChain.
+ if (!IsConstWithIntScalarType(_, inst, word_index) &&
+ !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << ext_inst_name() << ": expected operand Indexes is "
+ << "OpConstant, DebugGlobalVariable, or "
+ << "type is OpConstant with an integer scalar type";
+ }
+ }
+ break;
+ }
+
+ // TODO: Add validation rules for remaining cases as well.
+ case CommonDebugInfoDebugTypePtrToMember:
+ case CommonDebugInfoDebugTypeTemplateTemplateParameter:
+ case CommonDebugInfoDebugTypeTemplateParameterPack:
+ case CommonDebugInfoDebugLexicalBlockDiscriminator:
+ case CommonDebugInfoDebugInlinedVariable:
+ case CommonDebugInfoDebugMacroDef:
+ case CommonDebugInfoDebugMacroUndef:
+ case CommonDebugInfoDebugImportedEntity:
+ break;
+ case CommonDebugInfoInstructionsMax:
+ assert(0);
+ break;
}
-
- // TODO: Add validation rules for remaining cases as well.
- case OpenCLDebugInfo100DebugTypePtrToMember:
- case OpenCLDebugInfo100DebugTypeTemplateTemplateParameter:
- case OpenCLDebugInfo100DebugTypeTemplateParameterPack:
- case OpenCLDebugInfo100DebugLexicalBlockDiscriminator:
- case OpenCLDebugInfo100DebugInlinedVariable:
- case OpenCLDebugInfo100DebugMacroDef:
- case OpenCLDebugInfo100DebugMacroUndef:
- case OpenCLDebugInfo100DebugImportedEntity:
- case OpenCLDebugInfo100DebugModuleINTEL:
- break;
- case OpenCLDebugInfo100InstructionsMax:
- assert(0);
- break;
}
} else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp
index d16d48e269a..d3ef5386c82 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp
@@ -27,6 +27,10 @@ namespace spvtools {
namespace val {
namespace {
+// Limit the number of checked locations to 4096. Multiplied by 4 to represent
+// all the components. This limit is set to be well beyond practical use cases.
+const uint32_t kMaxLocations = 4096 * 4;
+
// Returns true if \c inst is an input or output variable.
bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) {
if (is_spv_1_4) {
@@ -347,6 +351,11 @@ spv_result_t GetLocationsForVariable(
uint32_t num_components = NumConsumedComponents(_, sub_type);
uint32_t array_location = location + (num_locations * array_idx);
uint32_t start = array_location * 4;
+ if (kMaxLocations <= start) {
+ // Too many locations, give up.
+ break;
+ }
+
uint32_t end = (array_location + num_locations) * 4;
if (num_components != 0) {
start += component;
@@ -416,6 +425,11 @@ spv_result_t GetLocationsForVariable(
}
uint32_t start = location * 4;
+ if (kMaxLocations <= start) {
+ // Too many locations, give up.
+ continue;
+ }
+
uint32_t end = (location + num_locations) * 4;
if (num_components != 0) {
start += component;
@@ -454,6 +468,7 @@ spv_result_t ValidateLocations(ValidationState_t& _,
std::unordered_set<uint32_t> input_locations;
std::unordered_set<uint32_t> output_locations_index0;
std::unordered_set<uint32_t> output_locations_index1;
+ std::unordered_set<uint32_t> seen;
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);
@@ -462,6 +477,11 @@ spv_result_t ValidateLocations(ValidationState_t& _,
storage_class != SpvStorageClassOutput) {
continue;
}
+ if (!seen.insert(interface_id).second) {
+ // Pre-1.4 an interface variable could be listed multiple times in an
+ // entry point. Validation for 1.4 or later is done elsewhere.
+ continue;
+ }
auto locations = (storage_class == SpvStorageClassInput)
? &input_locations
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp
index b53f991e87d..d5823219d93 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp
@@ -17,6 +17,7 @@
#include <cassert>
#include "DebugInfo.h"
+#include "NonSemanticShaderDebugInfo100.h"
#include "OpenCLDebugInfo100.h"
#include "source/diagnostic.h"
#include "source/opcode.h"
@@ -37,17 +38,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _,
const Instruction* inst, SpvOp opcode) {
switch (opcode) {
case SpvOpExtInst:
- if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
- // non-semantic extinst opcodes are allowed beginning in the types
- // section, but since they must name a return type they cannot be the
- // first instruction in the types section. Therefore check that we are
- // already in it.
- if (_.current_layout_section() < kLayoutTypes) {
- return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
- << "Non-semantic OpExtInst must not appear before types "
- << "section";
- }
- } else if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
+ if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
const uint32_t ext_inst_index = inst->word(4);
bool local_debug_info = false;
if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
@@ -59,6 +50,20 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _,
ext_inst_key == OpenCLDebugInfo100DebugValue) {
local_debug_info = true;
}
+ } else if (inst->ext_inst_type() ==
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
+ const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
+ NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
+ if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugValue ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugLine ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine ||
+ ext_inst_key ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
+ local_debug_info = true;
+ }
} else {
const DebugInfoInstructions ext_inst_key =
DebugInfoInstructions(ext_inst_index);
@@ -94,6 +99,16 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _,
<< "declarations)";
}
}
+ } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
+ // non-semantic extinst opcodes are allowed beginning in the types
+ // section, but since they must name a return type they cannot be the
+ // first instruction in the types section. Therefore check that we are
+ // already in it.
+ if (_.current_layout_section() < kLayoutTypes) {
+ return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
+ << "Non-semantic OpExtInst must not appear before types "
+ << "section";
+ }
} else {
// otherwise they must be used in a block
if (_.current_layout_section() < kLayoutFunctionDefinitions) {
@@ -230,20 +245,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
break;
case SpvOpExtInst:
- if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
- // non-semantic extinst opcodes are allowed beginning in the types
- // section, but must either be placed outside a function declaration,
- // or inside a block.
- if (_.current_layout_section() < kLayoutTypes) {
- return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
- << "Non-semantic OpExtInst must not appear before types "
- << "section";
- } else if (_.in_function_body() && _.in_block() == false) {
- return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
- << "Non-semantic OpExtInst within function definition must "
- "appear in a block";
- }
- } else if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
+ if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
const uint32_t ext_inst_index = inst->word(4);
bool local_debug_info = false;
if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
@@ -255,6 +257,20 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
ext_inst_key == OpenCLDebugInfo100DebugValue) {
local_debug_info = true;
}
+ } else if (inst->ext_inst_type() ==
+ SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
+ const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
+ NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
+ if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugValue ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugLine ||
+ ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine ||
+ ext_inst_key ==
+ NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
+ local_debug_info = true;
+ }
} else {
const DebugInfoInstructions ext_inst_key =
DebugInfoInstructions(ext_inst_index);
@@ -290,6 +306,19 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _,
<< "declarations)";
}
}
+ } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
+ // non-semantic extinst opcodes are allowed beginning in the types
+ // section, but must either be placed outside a function declaration,
+ // or inside a block.
+ if (_.current_layout_section() < kLayoutTypes) {
+ return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
+ << "Non-semantic OpExtInst must not appear before types "
+ << "section";
+ } else if (_.in_function_body() && _.in_block() == false) {
+ return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
+ << "Non-semantic OpExtInst within function definition must "
+ "appear in a block";
+ }
} else {
// otherwise they must be used in a block
if (_.in_block() == false) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp
index a4bc0faba8d..a7b0f82d5d1 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp
@@ -893,6 +893,12 @@ spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
<< "'s type.";
}
+ if (!_.options()->before_hlsl_legalization &&
+ _.ContainsRuntimeArray(inst->type_id())) {
+ return _.diag(SPV_ERROR_INVALID_ID, inst)
+ << "Cannot load a runtime-sized array";
+ }
+
if (auto error = CheckMemoryAccess(_, inst, 3)) return error;
if (_.HasCapability(SpvCapabilityShader) &&
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp
index 79f82d8d76d..4fb6d9b9686 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp
@@ -225,6 +225,13 @@ spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
}
}
}
+ if (i.opcode() == SpvOpExecutionModeId) {
+ const auto mode = i.GetOperandAs<SpvExecutionMode>(1);
+ if (mode == SpvExecutionModeLocalSizeId) {
+ ok = true;
+ break;
+ }
+ }
}
if (!ok) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
@@ -429,6 +436,10 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _,
break;
case SpvExecutionModeLocalSize:
case SpvExecutionModeLocalSizeId:
+ if (mode == SpvExecutionModeLocalSizeId && !_.IsLocalSizeIdAllowed())
+ return _.diag(SPV_ERROR_INVALID_DATA, inst)
+ << "LocalSizeId mode is not allowed by the current environment.";
+
if (!std::all_of(models->begin(), models->end(),
[&_](const SpvExecutionModel& model) {
switch (model) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_type.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_type.cpp
index 612fc5c2ce1..4376b52c6d4 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_type.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validate_type.cpp
@@ -596,7 +596,7 @@ 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(rows_id)
+ << "OpTypeCooperativeMatrixNV Cols <id> '" << _.getIdName(cols_id)
<< "' is not a constant instruction with scalar integer type.";
}
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp
index 52821636bff..10ebd68ceb9 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp
@@ -175,6 +175,9 @@ ValidationState_t::ValidationState_t(const spv_const_context ctx,
}
}
+ // LocalSizeId is always allowed in non-Vulkan environments.
+ features_.env_allow_localsizeid = !spvIsVulkanEnv(env);
+
// Only attempt to count if we have words, otherwise let the other validation
// fail and generate an error.
if (num_words > 0) {
@@ -729,19 +732,19 @@ uint32_t ValidationState_t::GetBitWidth(uint32_t id) const {
bool ValidationState_t::IsVoidType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeVoid;
+ return inst && inst->opcode() == SpvOpTypeVoid;
}
bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeFloat;
+ return inst && inst->opcode() == SpvOpTypeFloat;
}
bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeVector) {
return IsFloatScalarType(GetComponentType(id));
@@ -752,7 +755,9 @@ bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeFloat) {
return true;
@@ -767,13 +772,14 @@ bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
bool ValidationState_t::IsIntScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeInt;
+ return inst && inst->opcode() == SpvOpTypeInt;
}
bool ValidationState_t::IsIntVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeVector) {
return IsIntScalarType(GetComponentType(id));
@@ -784,7 +790,9 @@ bool ValidationState_t::IsIntVectorType(uint32_t id) const {
bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeInt) {
return true;
@@ -799,13 +807,14 @@ bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeInt && inst->word(3) == 0;
+ return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 0;
}
bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeVector) {
return IsUnsignedIntScalarType(GetComponentType(id));
@@ -816,13 +825,14 @@ bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
bool ValidationState_t::IsSignedIntScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeInt && inst->word(3) == 1;
+ return inst && inst->opcode() == SpvOpTypeInt && inst->word(3) == 1;
}
bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeVector) {
return IsSignedIntScalarType(GetComponentType(id));
@@ -833,13 +843,14 @@ bool ValidationState_t::IsSignedIntVectorType(uint32_t id) const {
bool ValidationState_t::IsBoolScalarType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeBool;
+ return inst && inst->opcode() == SpvOpTypeBool;
}
bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeVector) {
return IsBoolScalarType(GetComponentType(id));
@@ -850,7 +861,9 @@ bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeBool) {
return true;
@@ -865,7 +878,9 @@ bool ValidationState_t::IsBoolScalarOrVectorType(uint32_t id) const {
bool ValidationState_t::IsFloatMatrixType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
+ if (!inst) {
+ return false;
+ }
if (inst->opcode() == SpvOpTypeMatrix) {
return IsFloatScalarType(GetComponentType(id));
@@ -920,8 +935,7 @@ bool ValidationState_t::GetStructMemberTypes(
bool ValidationState_t::IsPointerType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypePointer;
+ return inst && inst->opcode() == SpvOpTypePointer;
}
bool ValidationState_t::GetPointerTypeInfo(uint32_t id, uint32_t* data_type,
@@ -939,8 +953,7 @@ bool ValidationState_t::GetPointerTypeInfo(uint32_t id, uint32_t* data_type,
bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const {
const Instruction* inst = FindDef(id);
- assert(inst);
- return inst->opcode() == SpvOpTypeCooperativeMatrixNV;
+ return inst && inst->opcode() == SpvOpTypeCooperativeMatrixNV;
}
bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const {
@@ -1262,16 +1275,13 @@ const Instruction* ValidationState_t::TracePointer(
return base_ptr;
}
-bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type,
- uint32_t width) const {
- if (type != SpvOpTypeInt && type != SpvOpTypeFloat) return false;
-
+bool ValidationState_t::ContainsType(
+ uint32_t id, const std::function<bool(const Instruction*)>& f,
+ bool traverse_all_types) const {
const auto inst = FindDef(id);
if (!inst) return false;
- if (inst->opcode() == type) {
- return inst->GetOperandAs<uint32_t>(1u) == width;
- }
+ if (f(inst)) return true;
switch (inst->opcode()) {
case SpvOpTypeArray:
@@ -1281,24 +1291,45 @@ bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type,
case SpvOpTypeImage:
case SpvOpTypeSampledImage:
case SpvOpTypeCooperativeMatrixNV:
- return ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(1u), type,
- width);
+ return ContainsType(inst->GetOperandAs<uint32_t>(1u), f,
+ traverse_all_types);
case SpvOpTypePointer:
if (IsForwardPointer(id)) return false;
- return ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(2u), type,
- width);
+ if (traverse_all_types) {
+ return ContainsType(inst->GetOperandAs<uint32_t>(2u), f,
+ traverse_all_types);
+ }
+ break;
case SpvOpTypeFunction:
- case SpvOpTypeStruct: {
+ case SpvOpTypeStruct:
+ if (inst->opcode() == SpvOpTypeFunction && !traverse_all_types) {
+ return false;
+ }
for (uint32_t i = 1; i < inst->operands().size(); ++i) {
- if (ContainsSizedIntOrFloatType(inst->GetOperandAs<uint32_t>(i), type,
- width))
+ if (ContainsType(inst->GetOperandAs<uint32_t>(i), f,
+ traverse_all_types)) {
return true;
+ }
}
- return false;
- }
+ break;
default:
- return false;
+ break;
}
+
+ return false;
+}
+
+bool ValidationState_t::ContainsSizedIntOrFloatType(uint32_t id, SpvOp type,
+ uint32_t width) const {
+ if (type != SpvOpTypeInt && type != SpvOpTypeFloat) return false;
+
+ const auto f = [type, width](const Instruction* inst) {
+ if (inst->opcode() == type) {
+ return inst->GetOperandAs<uint32_t>(1u) == width;
+ }
+ return false;
+ };
+ return ContainsType(id, f);
}
bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const {
@@ -1313,6 +1344,13 @@ bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const {
return false;
}
+bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const {
+ const auto f = [](const Instruction* inst) {
+ return inst->opcode() == SpvOpTypeRuntimeArray;
+ };
+ return ContainsType(id, f, /* traverse_all_types = */ false);
+}
+
bool ValidationState_t::IsValidStorageClass(
SpvStorageClass storage_class) const {
if (spvIsVulkanEnv(context()->target_env)) {
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.h b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.h
index 57634bf4a0b..2ddfa4a9383 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.h
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/val/validation_state.h
@@ -90,23 +90,6 @@ class ValidationState_t {
// conversion opcodes
bool use_int8_type = false;
- // Use scalar block layout. See VK_EXT_scalar_block_layout:
- // Defines scalar alignment:
- // - scalar alignment equals the scalar size in bytes
- // - array alignment is same as its element alignment
- // - array alignment is max alignment of any of its members
- // - vector alignment is same as component alignment
- // - matrix alignment is same as component alignment
- // For struct in Uniform, StorageBuffer, PushConstant:
- // - Offset of a member is multiple of scalar alignment of that member
- // - ArrayStride and MatrixStride are multiples of scalar alignment
- // Members need not be listed in offset order
- bool scalar_block_layout = false;
-
- // Use scalar block layout (as defined above) for Workgroup block
- // variables. See VK_KHR_workgroup_memory_explicit_layout.
- bool workgroup_scalar_block_layout = false;
-
// SPIR-V 1.4 allows us to select between any two composite values
// of the same type.
bool select_between_composites = false;
@@ -121,6 +104,9 @@ class ValidationState_t {
// SPIR-V 1.4 allows Function and Private variables to be NonWritable
bool nonwritable_var_in_function_or_private = false;
+
+ // Whether LocalSizeId execution mode is allowed by the environment.
+ bool env_allow_localsizeid = false;
};
ValidationState_t(const spv_const_context context,
@@ -493,6 +479,12 @@ class ValidationState_t {
return features_.env_relaxed_block_layout || options()->relax_block_layout;
}
+ // Returns true if allowing localsizeid, either because the environment always
+ // allows it, or because it is enabled from the command-line.
+ bool IsLocalSizeIdAllowed() const {
+ return features_.env_allow_localsizeid || options()->allow_localsizeid;
+ }
+
/// Sets the struct nesting depth for a given struct ID
void set_struct_nesting_depth(uint32_t id, uint32_t depth) {
struct_nesting_depth_[id] = depth;
@@ -595,6 +587,17 @@ class ValidationState_t {
// 16-bit float that is not generally enabled for use.
bool ContainsLimitedUseIntOrFloatType(uint32_t id) const;
+ // Returns true if |id| is a type that contains a runtime-sized array.
+ // Does not consider a pointers as contains the array.
+ bool ContainsRuntimeArray(uint32_t id) const;
+
+ // Generic type traversal.
+ // Only traverse pointers and functions if |traverse_all_types| is true.
+ // Recursively tests |f| against the type hierarchy headed by |id|.
+ bool ContainsType(uint32_t id,
+ 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;
diff --git a/3rdparty/bgfx/CONTRIBUTING.md b/3rdparty/bgfx/CONTRIBUTING.md
index dd1e6375d5b..d45bd53d44b 100644
--- a/3rdparty/bgfx/CONTRIBUTING.md
+++ b/3rdparty/bgfx/CONTRIBUTING.md
@@ -1,8 +1,9 @@
## How to contribute?
Everyone is welcome to contribute to bgfx by submitting bug reports, testing on
-different platforms, writing examples, improving documentation, profiling and
-optimizing, helping newcomers, telling others about bgfx, etc.
+different platforms, writing examples (see [Help Needed](https://github.com/bkaradzic/bgfx/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+needed%22)
+for ideas), improving documentation, profiling and optimizing, helping
+newcomers, telling others about bgfx, etc.
If you have just quick oneliner question it's prefereable to ask it at chat
https://discord.gg/9eMbv7J instead opening new issue.
diff --git a/3rdparty/bgfx/README.md b/3rdparty/bgfx/README.md
index 8c56b96c60c..9acdf367b30 100644
--- a/3rdparty/bgfx/README.md
+++ b/3rdparty/bgfx/README.md
@@ -16,7 +16,6 @@
<a href="#license-bsd-2-clause">License</a>
</p>
-[![Build Status](https://travis-ci.com/bkaradzic/bgfx.svg?branch=master)](https://travis-ci.com/bkaradzic/bgfx)
[![Build status](https://ci.appveyor.com/api/projects/status/ipa3ojgeaet1oko5?svg=true)](https://ci.appveyor.com/project/bkaradzic/bgfx)
[![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://bkaradzic.github.io/bgfx/license.html)
[![Join the chat at https://discord.gg/9eMbv7J](https://img.shields.io/discord/712512073522872352?color=%237289DA&label=bgfx&logo=discord&logoColor=white)](https://discord.gg/9eMbv7J)
@@ -24,7 +23,6 @@
* [GitHub Discussions](https://github.com/bkaradzic/bgfx/discussions)
* [Discord Chat](https://discord.gg/9eMbv7J)
* [AppVeyor CI](https://ci.appveyor.com/project/bkaradzic/bgfx)
- * [Travis CI](https://travis-ci.com/bkaradzic/bgfx)
[What is it?](https://bkaradzic.github.io/bgfx/overview.html)
-------------------------------------------------------------
@@ -470,6 +468,26 @@ https://embersword.com
![Ember-Sword-ConceptArt5](https://user-images.githubusercontent.com/814772/120714133-a860ca80-c477-11eb-8680-f5a948dfd050.png)
+## Off The Road Unleashed
+
+Off The Road Unleashed is a sandbox driving game for the Nintendo Switch.
+If you see a vehicle you bet you can hop into it! Pilot big rigs, helicopters, boats, airplanes or even trains. Sand dunes, frozen plains, mountains to climb and conquer.
+
+https://www.nintendo.com/games/detail/off-the-road-unleashed-switch/
+
+<a href="http://www.youtube.com/watch?feature=player_embedded&v=cwDR0Wj3LO4"
+target="_blank"><img src="http://img.youtube.com/vi/cwDR0Wj3LO4/0.jpg"
+alt="Off The Road Unleashed"
+width="640" height="480" border="0" /></a>
+
+## Guild Wars 2
+
+Guild Wars 2 is an online role-playing game with fast-paced action combat, a rich and detailed universe of stories, awe-inspiring landscapes to explore, two challenging player vs. player modes—and no subscription fees!
+
+https://www.guildwars2.com/
+
+![Guild-Wars-2-wallpaper](https://d3b4yo2b5lbfy.cloudfront.net/wp-content/uploads/wallpapers/GuildWars2-01-800x600.jpg)
+
[License (BSD 2-clause)](https://bkaradzic.github.io/bgfx/license.html)
-----------------------------------------------------------------------
diff --git a/3rdparty/bgfx/bindings/bf/bgfx.bf b/3rdparty/bgfx/bindings/bf/bgfx.bf
index 31eb191a90d..89dfa303b4a 100644
--- a/3rdparty/bgfx/bindings/bf/bgfx.bf
+++ b/3rdparty/bgfx/bindings/bf/bgfx.bf
@@ -1335,6 +1335,11 @@ public static class bgfx
Noop,
/// <summary>
+ /// AGC
+ /// </summary>
+ Agc,
+
+ /// <summary>
/// Direct3D 9.0
/// </summary>
Direct3D9,
diff --git a/3rdparty/bgfx/bindings/cs/bgfx.cs b/3rdparty/bgfx/bindings/cs/bgfx.cs
index 0d5ed0377a7..c445bece423 100644
--- a/3rdparty/bgfx/bindings/cs/bgfx.cs
+++ b/3rdparty/bgfx/bindings/cs/bgfx.cs
@@ -1332,6 +1332,11 @@ public static partial class bgfx
Noop,
/// <summary>
+ /// AGC
+ /// </summary>
+ Agc,
+
+ /// <summary>
/// Direct3D 9.0
/// </summary>
Direct3D9,
diff --git a/3rdparty/bgfx/bindings/d/types.d b/3rdparty/bgfx/bindings/d/types.d
index 9975858a6db..c3c92790e0a 100644
--- a/3rdparty/bgfx/bindings/d/types.d
+++ b/3rdparty/bgfx/bindings/d/types.d
@@ -427,6 +427,7 @@ enum bgfx_fatal_t
enum bgfx_renderer_type_t
{
BGFX_RENDERER_TYPE_NOOP, /// No rendering.
+ BGFX_RENDERER_TYPE_AGC, /// AGC
BGFX_RENDERER_TYPE_DIRECT3D9, /// Direct3D 9.0
BGFX_RENDERER_TYPE_DIRECT3D11, /// Direct3D 11.0
BGFX_RENDERER_TYPE_DIRECT3D12, /// Direct3D 12.0
diff --git a/3rdparty/bgfx/examples/18-ibl/ibl.cpp b/3rdparty/bgfx/examples/18-ibl/ibl.cpp
index f4cf1c5916c..3e2ab6a907b 100644
--- a/3rdparty/bgfx/examples/18-ibl/ibl.cpp
+++ b/3rdparty/bgfx/examples/18-ibl/ibl.cpp
@@ -291,8 +291,8 @@ struct Camera
struct Interp3f
{
- bx::Vec3 curr;
- bx::Vec3 dest;
+ bx::Vec3 curr = bx::init::None;
+ bx::Vec3 dest = bx::init::None;
};
Interp3f m_target;
diff --git a/3rdparty/bgfx/examples/28-wireframe/wireframe.cpp b/3rdparty/bgfx/examples/28-wireframe/wireframe.cpp
index b1c3d30f801..5529b2c2434 100644
--- a/3rdparty/bgfx/examples/28-wireframe/wireframe.cpp
+++ b/3rdparty/bgfx/examples/28-wireframe/wireframe.cpp
@@ -29,8 +29,8 @@ struct Camera
void reset()
{
- m_target.curr = { 0.0f, 0.0f, 0.0f };
- m_target.dest = { 0.0f, 0.0f, 0.0f };
+ m_target.curr = bx::init::Zero;
+ m_target.dest = bx::init::Zero;
m_pos.curr = { 0.0f, 0.0f, -2.0f };
m_pos.dest = { 0.0f, 0.0f, -2.0f };
@@ -135,8 +135,8 @@ struct Camera
struct Interp3f
{
- bx::Vec3 curr;
- bx::Vec3 dest;
+ bx::Vec3 curr = bx::init::None;
+ bx::Vec3 dest = bx::init::None;
};
Interp3f m_target;
diff --git a/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp
index 1b102fc3198..f7828b8925b 100644
--- a/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp
+++ b/3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp
@@ -601,7 +601,7 @@ void initA(Shape& _outShape, Shape::Type::Enum _type, bx::Vec3 _pos)
case Shape::Type::Plane:
{
- bx::Plane plane;
+ bx::Plane plane(bx::init::None);
bx::calcPlane(plane, bx::normalize(bx::Vec3{0.0f, 1.0f, 1.0f}), _pos);
_outShape = Shape(plane);
}
@@ -688,7 +688,7 @@ void initB(Shape& _outShape, Shape::Type::Enum _type, bx::Vec3 _pos)
case Shape::Type::Plane:
{
- bx::Plane plane;
+ bx::Plane plane(bx::init::None);
bx::calcPlane(plane, bx::normalize(bx::Vec3{1.0f, 1.0f, 0.0f}), _pos);
_outShape = Shape(plane);
}
@@ -999,7 +999,7 @@ public:
const bx::Vec3 normal = { 0.0f, 1.0f, 0.0f };
const bx::Vec3 pos = { 0.0f, -2.0f, 0.0f };
- bx::Plane plane;
+ bx::Plane plane(bx::init::None);
bx::calcPlane(plane, normal, pos);
dde.setColor(false
diff --git a/3rdparty/bgfx/examples/36-sky/sky.cpp b/3rdparty/bgfx/examples/36-sky/sky.cpp
index 40186e18a68..7c2d3bb98b4 100644
--- a/3rdparty/bgfx/examples/36-sky/sky.cpp
+++ b/3rdparty/bgfx/examples/36-sky/sky.cpp
@@ -63,7 +63,7 @@ namespace
typedef bx::Vec3 Color;
// HDTV rec. 709 matrix.
- static float M_XYZ2RGB[] =
+ static constexpr float M_XYZ2RGB[] =
{
3.240479f, -0.969256f, 0.055648f,
-1.53715f, 1.875991f, -0.204043f,
@@ -73,18 +73,18 @@ namespace
// Converts color repesentation from CIE XYZ to RGB color-space.
Color xyzToRgb(const Color& xyz)
{
- Color rgb;
+ Color rgb(bx::init::None);
rgb.x = M_XYZ2RGB[0] * xyz.x + M_XYZ2RGB[3] * xyz.y + M_XYZ2RGB[6] * xyz.z;
rgb.y = M_XYZ2RGB[1] * xyz.x + M_XYZ2RGB[4] * xyz.y + M_XYZ2RGB[7] * xyz.z;
rgb.z = M_XYZ2RGB[2] * xyz.x + M_XYZ2RGB[5] * xyz.y + M_XYZ2RGB[8] * xyz.z;
return rgb;
};
-
// Precomputed luminance of sunlight in XYZ colorspace.
// Computed using code from Game Engine Gems, Volume One, chapter 15. Implementation based on Dr. Richard Bird model.
// This table is used for piecewise linear interpolation. Transitions from and to 0.0 at sunset and sunrise are highly inaccurate
- static std::map<float, Color> sunLuminanceXYZTable = {
+ static std::map<float, Color> sunLuminanceXYZTable =
+ {
{ 5.0f, { 0.000000f, 0.000000f, 0.000000f } },
{ 7.0f, { 12.703322f, 12.989393f, 9.100411f } },
{ 8.0f, { 13.202644f, 13.597814f, 11.524929f } },
@@ -107,7 +107,8 @@ namespace
// This table is used for piecewise linear interpolation. Day/night transitions are highly inaccurate.
// The scale of luminance change in Day/night transitions is not preserved.
// Luminance at night was increased to eliminate need the of HDR render.
- static std::map<float, Color> skyLuminanceXYZTable = {
+ static std::map<float, Color> skyLuminanceXYZTable =
+ {
{ 0.0f, { 0.308f, 0.308f, 0.411f } },
{ 1.0f, { 0.308f, 0.308f, 0.410f } },
{ 2.0f, { 0.301f, 0.301f, 0.402f } },
@@ -136,7 +137,7 @@ namespace
// Turbidity tables. Taken from:
// A. J. Preetham, P. Shirley, and B. Smits. A Practical Analytic Model for Daylight. SIGGRAPH '99
// Coefficients correspond to xyY colorspace.
- static Color ABCDE[] =
+ static constexpr Color ABCDE[] =
{
{ -0.2592f, -0.2608f, -1.4630f },
{ 0.0008f, 0.0092f, 0.4275f },
@@ -144,7 +145,8 @@ namespace
{ -0.8989f, -1.6537f, -2.5771f },
{ 0.0452f, 0.0529f, 0.3703f },
};
- static Color ABCDE_t[] =
+
+ static constexpr Color ABCDE_t[] =
{
{ -0.0193f, -0.0167f, 0.1787f },
{ -0.0665f, -0.0950f, -0.3554f },
@@ -241,14 +243,14 @@ namespace
};
SunController()
- : m_latitude(50.0f)
+ : m_northDir(1.0f, 0.0f, 0.0f)
+ , m_sunDir(0.0f, -1.0f, 0.0f)
+ , m_upDir(0.0f, 1.0f, 0.0f)
+ , m_latitude(50.0f)
, m_month(June)
, m_eclipticObliquity(bx::toRad(23.4f) )
, m_delta(0.0f)
{
- m_northDir = { 1.0f, 0.0f, 0.0f };
- m_sunDir = { 0.0f, -1.0f, 0.0f };
- m_upDir = { 0.0f, 1.0f, 0.0f };
}
void Update(float _time)
diff --git a/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp b/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
index 55ecb4a6af0..9efbac4fa08 100644
--- a/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
+++ b/3rdparty/bgfx/examples/37-gpudrivenrendering/gpudrivenrendering.cpp
@@ -139,8 +139,8 @@ struct Camera
struct Interp3f
{
- bx::Vec3 curr;
- bx::Vec3 dest;
+ bx::Vec3 curr = bx::init::None;
+ bx::Vec3 dest = bx::init::None;
};
Interp3f m_target;
diff --git a/3rdparty/bgfx/examples/39-assao/cs_assao_generate_importance_map.sc b/3rdparty/bgfx/examples/39-assao/cs_assao_generate_importance_map.sc
index 584c40cf538..5e681d620c6 100644
--- a/3rdparty/bgfx/examples/39-assao/cs_assao_generate_importance_map.sc
+++ b/3rdparty/bgfx/examples/39-assao/cs_assao_generate_importance_map.sc
@@ -28,7 +28,7 @@ void main()
UNROLL
for( int i = 0; i < 4; i++ )
{
- vec4 vals = textureGather(s_finalSSAO, vec3( gatherUV, i ) );
+ vec4 vals = textureGather(s_finalSSAO, vec3( gatherUV, i ), 0);
// apply the same modifications that would have been applied in the main shader
vals = u_effectShadowStrength * vals;
diff --git a/3rdparty/bgfx/examples/39-assao/cs_assao_generate_q.sh b/3rdparty/bgfx/examples/39-assao/cs_assao_generate_q.sh
index fbd140af17c..f8d131afab3 100644
--- a/3rdparty/bgfx/examples/39-assao/cs_assao_generate_q.sh
+++ b/3rdparty/bgfx/examples/39-assao/cs_assao_generate_q.sh
@@ -238,11 +238,11 @@ void GenerateSSAOShadowsInternal( out float outShadowTerm, out vec4 outEdges, ou
float pixZ, pixLZ, pixTZ, pixRZ, pixBZ;
#if BGFX_SHADER_LANGUAGE_GLSL
- vec4 valuesUL = textureGather(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize + vec2(0.0,u_halfViewportPixelSize.y)).wzyx;
- vec4 valuesBR = textureGatherOffset(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize + vec2(0.0,u_halfViewportPixelSize.y), ivec2( 1, -1 ) ).wzyx;
+ vec4 valuesUL = textureGather(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize + vec2(0.0,u_halfViewportPixelSize.y), 0).wzyx;
+ vec4 valuesBR = textureGatherOffset(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize + vec2(0.0,u_halfViewportPixelSize.y), ivec2( 1, -1 ), 0).wzyx;
#else
- vec4 valuesUL = textureGather(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize );
- vec4 valuesBR = textureGatherOffset(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize, ivec2( 1, 1 ) );
+ vec4 valuesUL = textureGather(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize, 0);
+ vec4 valuesBR = textureGatherOffset(s_viewspaceDepthSourceMirror, SVPosRounded * u_halfViewportPixelSize, ivec2( 1, 1 ), 0);
#endif
// get this pixel's viewspace depth
diff --git a/3rdparty/bgfx/examples/39-assao/cs_assao_smart_blur.sc b/3rdparty/bgfx/examples/39-assao/cs_assao_smart_blur.sc
index 45e7c5cf720..15d13ff2c85 100644
--- a/3rdparty/bgfx/examples/39-assao/cs_assao_smart_blur.sc
+++ b/3rdparty/bgfx/examples/39-assao/cs_assao_smart_blur.sc
@@ -39,11 +39,11 @@ vec2 SampleBlurred( ivec2 inPos, vec2 coord )
vec4 edgesLRTB = UnpackEdges( packedEdges );
#if BGFX_SHADER_LANGUAGE_GLSL
- vec4 valuesUL = textureGather(s_blurInput, vec3(coord - u_halfViewportPixelSize * 0.5 + vec2(0.0,u_halfViewportPixelSize.y), 0.0)).wzyx;
- vec4 valuesBR = textureGather(s_blurInput, vec3(coord + u_halfViewportPixelSize * 0.5 + vec2(0.0,-u_halfViewportPixelSize.y), 0.0)).wzyx;
+ vec4 valuesUL = textureGather(s_blurInput, vec3(coord - u_halfViewportPixelSize * 0.5 + vec2(0.0,u_halfViewportPixelSize.y), 0.0), 0).wzyx;
+ vec4 valuesBR = textureGather(s_blurInput, vec3(coord + u_halfViewportPixelSize * 0.5 + vec2(0.0,-u_halfViewportPixelSize.y), 0.0), 0).wzyx;
#else
- vec4 valuesUL = textureGather(s_blurInput, vec3(coord - u_halfViewportPixelSize * 0.5, 0.0));
- vec4 valuesBR = textureGather(s_blurInput, vec3(coord + u_halfViewportPixelSize * 0.5, 0.0));
+ vec4 valuesUL = textureGather(s_blurInput, vec3(coord - u_halfViewportPixelSize * 0.5, 0.0), 0);
+ vec4 valuesBR = textureGather(s_blurInput, vec3(coord + u_halfViewportPixelSize * 0.5, 0.0), 0);
#endif
float ssaoValue = valuesUL.y;
diff --git a/3rdparty/bgfx/examples/common/bgfx_utils.cpp b/3rdparty/bgfx/examples/common/bgfx_utils.cpp
index 2ee9c0a6a1f..6573b882858 100644
--- a/3rdparty/bgfx/examples/common/bgfx_utils.cpp
+++ b/3rdparty/bgfx/examples/common/bgfx_utils.cpp
@@ -108,6 +108,7 @@ static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name
case bgfx::RendererType::Direct3D9: shaderPath = "shaders/dx9/"; break;
case bgfx::RendererType::Direct3D11:
case bgfx::RendererType::Direct3D12: shaderPath = "shaders/dx11/"; break;
+ case bgfx::RendererType::Agc:
case bgfx::RendererType::Gnm: shaderPath = "shaders/pssl/"; break;
case bgfx::RendererType::Metal: shaderPath = "shaders/metal/"; break;
case bgfx::RendererType::Nvn: shaderPath = "shaders/nvn/"; break;
diff --git a/3rdparty/bgfx/examples/common/bounds.cpp b/3rdparty/bgfx/examples/common/bounds.cpp
index 835062d149a..7c92cb3da9f 100644
--- a/3rdparty/bgfx/examples/common/bounds.cpp
+++ b/3rdparty/bgfx/examples/common/bounds.cpp
@@ -128,7 +128,8 @@ void aabbTransformToObb(Obb& _obb, const Aabb& _aabb, const float* _mtx)
void toAabb(Aabb& _outAabb, const void* _vertices, uint32_t _numVertices, uint32_t _stride)
{
- Vec3 mn, mx;
+ Vec3 mn(init::None);
+ Vec3 mx(init::None);
uint8_t* vertex = (uint8_t*)_vertices;
mn = mx = load<Vec3>(vertex);
@@ -149,7 +150,8 @@ void toAabb(Aabb& _outAabb, const void* _vertices, uint32_t _numVertices, uint32
void toAabb(Aabb& _outAabb, const float* _mtx, const void* _vertices, uint32_t _numVertices, uint32_t _stride)
{
- Vec3 mn, mx;
+ Vec3 mn(init::None);
+ Vec3 mx(init::None);
uint8_t* vertex = (uint8_t*)_vertices;
mn = mx = mul(load<Vec3>(vertex), _mtx);
@@ -282,7 +284,7 @@ void calcMinBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _num
uint8_t* vertex = (uint8_t*)_vertices;
- Vec3 center;
+ Vec3 center(init::None);
float* position = (float*)&vertex[0];
center.x = position[0];
center.y = position[1];
@@ -500,9 +502,7 @@ bool intersect(const Ray& _ray, const Obb& _obb, Hit* _hit)
bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit)
{
- Plane plane;
- plane.normal = _disk.normal;
- plane.dist = -dot(_disk.center, _disk.normal);
+ Plane plane(_disk.normal, -dot(_disk.center, _disk.normal) );
Hit tmpHit;
_hit = NULL != _hit ? _hit : &tmpHit;
@@ -597,8 +597,8 @@ static bool intersect(const Ray& _ray, const Cylinder& _cylinder, bool _capsule,
return intersect(_ray, sphere, _hit);
}
- Plane plane;
- Vec3 pos;
+ Plane plane(init::None);
+ Vec3 pos(init::None);
if (0.0f >= height)
{
@@ -866,6 +866,30 @@ void calcPlane(Plane& _outPlane, const Triangle& _triangle)
struct Interval
{
+ Interval(float _val)
+ : start(_val)
+ , end(_val)
+ {
+ }
+
+ Interval(float _start, float _end)
+ : start(_start)
+ , end(_end)
+ {
+ }
+
+ void set(float _val)
+ {
+ start = _val;
+ end = _val;
+ }
+
+ void expand(float _val)
+ {
+ start = min(_val, start);
+ end = max(_val, end);
+ }
+
float start;
float end;
};
@@ -882,10 +906,22 @@ float projectToAxis(const Vec3& _axis, const Vec3& _point)
return dot(_axis, _point);
}
+Interval projectToAxis(const Vec3& _axis, const Vec3* _points, uint32_t _num)
+{
+ Interval interval(projectToAxis(_axis, _points[0]) );
+
+ for (uint32_t ii = 1; ii < _num; ++ii)
+ {
+ interval.expand(projectToAxis(_axis, _points[ii]) );
+ }
+
+ return interval;
+}
+
Interval projectToAxis(const Vec3& _axis, const Aabb& _aabb)
{
- const float extent = bx::abs(dot(abs(_axis), getExtents(_aabb) ) );
- const float center = dot( _axis , getCenter (_aabb) );
+ const float extent = bx::abs(projectToAxis(abs(_axis), getExtents(_aabb) ) );
+ const float center = projectToAxis( _axis , getCenter (_aabb) );
return
{
center - extent,
@@ -895,9 +931,9 @@ Interval projectToAxis(const Vec3& _axis, const Aabb& _aabb)
Interval projectToAxis(const Vec3& _axis, const Triangle& _triangle)
{
- const float a0 = dot(_axis, _triangle.v0);
- const float a1 = dot(_axis, _triangle.v1);
- const float a2 = dot(_axis, _triangle.v2);
+ const float a0 = projectToAxis(_axis, _triangle.v0);
+ const float a1 = projectToAxis(_axis, _triangle.v1);
+ const float a2 = projectToAxis(_axis, _triangle.v2);
return
{
min(a0, a1, a2),
@@ -907,11 +943,16 @@ Interval projectToAxis(const Vec3& _axis, const Triangle& _triangle)
struct Srt
{
- Quaternion rotation;
- Vec3 translation;
- Vec3 scale;
+ Quaternion rotation = init::Identity;
+ Vec3 translation = init::Zero;
+ Vec3 scale = init::Zero;
};
+Srt toSrt(const Aabb& _aabb)
+{
+ return { init::Identity, getCenter(_aabb), getExtents(_aabb) };
+}
+
Srt toSrt(const void* _mtx)
{
Srt result;
@@ -1026,8 +1067,8 @@ bool isNearZero(const Vec3& _v)
struct Line
{
- Vec3 pos;
- Vec3 dir;
+ Vec3 pos = init::None;
+ Vec3 dir = init::None;
};
inline Vec3 getPointAt(const Line& _line, float _t)
@@ -1208,7 +1249,7 @@ Vec3 closestPoint(const Aabb& _aabb, const Vec3& _point)
Vec3 closestPoint(const Obb& _obb, const Vec3& _point)
{
- Srt srt = toSrt(_obb.mtx);
+ const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
@@ -1222,7 +1263,7 @@ Vec3 closestPoint(const Obb& _obb, const Vec3& _point)
Vec3 closestPoint(const Triangle& _triangle, const Vec3& _point)
{
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _triangle);
const Vec3 pos = closestPoint(plane, _point);
@@ -1246,12 +1287,9 @@ bool overlap(const Aabb& _aabb, const Vec3& _pos)
bool overlap(const Aabb& _aabbA, const Aabb& _aabbB)
{
return true
- && _aabbA.max.x > _aabbB.min.x
- && _aabbB.max.x > _aabbA.min.x
- && _aabbA.max.y > _aabbB.min.y
- && _aabbB.max.y > _aabbA.min.y
- && _aabbA.max.z > _aabbB.min.z
- && _aabbB.max.z > _aabbA.min.z
+ && overlap(Interval{_aabbA.min.x, _aabbA.max.x}, Interval{_aabbB.min.x, _aabbB.max.x})
+ && overlap(Interval{_aabbA.min.y, _aabbA.max.y}, Interval{_aabbB.min.y, _aabbB.max.y})
+ && overlap(Interval{_aabbA.min.z, _aabbA.max.z}, Interval{_aabbB.min.z, _aabbB.max.z})
;
}
@@ -1284,7 +1322,7 @@ bool overlap(const Aabb& _aabb, const Triangle& _triangle)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _triangle);
if (!overlap(_aabb, plane) )
@@ -1343,16 +1381,88 @@ bool overlap(const Aabb& _aabb, const Disk& _disk)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
return overlap(_aabb, plane);
}
+static void calcObbVertices(
+ bx::Vec3* _outVertices
+ , const bx::Vec3& _axisX
+ , const bx::Vec3& _axisY
+ , const bx::Vec3& _axisZ
+ , const bx::Vec3& _pos
+ , const bx::Vec3& _scale
+ )
+{
+ const Vec3 ax = mul(_axisX, _scale.x);
+ const Vec3 ay = mul(_axisY, _scale.y);
+ const Vec3 az = mul(_axisZ, _scale.z);
+
+ const Vec3 ppx = add(_pos, ax);
+ const Vec3 pmx = sub(_pos, ax);
+ const Vec3 ypz = add(ay, az);
+ const Vec3 ymz = sub(ay, az);
+
+ _outVertices[0] = sub(pmx, ymz);
+ _outVertices[1] = sub(ppx, ymz);
+ _outVertices[2] = add(ppx, ymz);
+ _outVertices[3] = add(pmx, ymz);
+ _outVertices[4] = sub(pmx, ypz);
+ _outVertices[5] = sub(ppx, ypz);
+ _outVertices[6] = add(ppx, ypz);
+ _outVertices[7] = add(pmx, ypz);
+}
+
+static bool overlaps(const Vec3& _axis, const Vec3* _vertsA, const Vec3* _vertsB)
+{
+ Interval ia = projectToAxis(_axis, _vertsA, 8);
+ Interval ib = projectToAxis(_axis, _vertsB, 8);
+
+ return overlap(ia, ib);
+}
+
+static bool overlap(const Srt& _srtA, const Srt& _srtB)
+{
+ const Vec3 ax = toXAxis(_srtA.rotation);
+ const Vec3 ay = toYAxis(_srtA.rotation);
+ const Vec3 az = toZAxis(_srtA.rotation);
+
+ const Vec3 bx = toXAxis(_srtB.rotation);
+ const Vec3 by = toYAxis(_srtB.rotation);
+ const Vec3 bz = toZAxis(_srtB.rotation);
+
+ Vec3 vertsA[8] = { init::None, init::None, init::None, init::None, init::None, init::None, init::None, init::None };
+ calcObbVertices(vertsA, ax, ay, az, init::Zero, _srtA.scale);
+
+ Vec3 vertsB[8] = { init::None, init::None, init::None, init::None, init::None, init::None, init::None, init::None };
+ calcObbVertices(vertsB, bx, by, bz, sub(_srtB.translation, _srtA.translation), _srtB.scale);
+
+ return overlaps(ax, vertsA, vertsB)
+ && overlaps(ay, vertsA, vertsB)
+ && overlaps(az, vertsA, vertsB)
+ && overlaps(bx, vertsA, vertsB)
+ && overlaps(by, vertsA, vertsB)
+ && overlaps(bz, vertsA, vertsB)
+ && overlaps(cross(ax, bx), vertsA, vertsB)
+ && overlaps(cross(ax, by), vertsA, vertsB)
+ && overlaps(cross(ax, bz), vertsA, vertsB)
+ && overlaps(cross(ay, bx), vertsA, vertsB)
+ && overlaps(cross(ay, by), vertsA, vertsB)
+ && overlaps(cross(ay, bz), vertsA, vertsB)
+ && overlaps(cross(az, bx), vertsA, vertsB)
+ && overlaps(cross(az, by), vertsA, vertsB)
+ && overlaps(cross(az, bz), vertsA, vertsB)
+ ;
+}
+
bool overlap(const Aabb& _aabb, const Obb& _obb)
{
- BX_UNUSED(_aabb, _obb);
- return false;
+ const Srt srtA = toSrt(_aabb);
+ const Srt srtB = toSrt(_obb.mtx);
+
+ return overlap(srtA, srtB);
}
bool overlap(const Capsule& _capsule, const Vec3& _pos)
@@ -1500,7 +1610,7 @@ bool overlap(const Cylinder& _cylinder, const Obb& _obb)
bool overlap(const Disk& _disk, const Vec3& _pos)
{
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
if (!isNearZero(distance(plane, _pos) ) )
@@ -1513,7 +1623,7 @@ bool overlap(const Disk& _disk, const Vec3& _pos)
bool overlap(const Disk& _disk, const Plane& _plane)
{
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
if (!overlap(plane, _plane) )
@@ -1531,7 +1641,7 @@ bool overlap(const Disk& _disk, const Capsule& _capsule)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
return overlap(_capsule, plane);
@@ -1539,10 +1649,10 @@ bool overlap(const Disk& _disk, const Capsule& _capsule)
bool overlap(const Disk& _diskA, const Disk& _diskB)
{
- Plane planeA;
+ Plane planeA(init::None);
calcPlane(planeA, _diskA.normal, _diskA.center);
- Plane planeB;
+ Plane planeB(init::None);
calcPlane(planeB, _diskB);
Line line;
@@ -1571,7 +1681,7 @@ bool overlap(const Disk& _disk, const Obb& _obb)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
return overlap(_obb, plane);
@@ -1579,7 +1689,7 @@ bool overlap(const Disk& _disk, const Obb& _obb)
bool overlap(const Obb& _obb, const Vec3& _pos)
{
- Srt srt = toSrt(_obb.mtx);
+ const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
@@ -1592,7 +1702,7 @@ bool overlap(const Obb& _obb, const Vec3& _pos)
bool overlap(const Obb& _obb, const Plane& _plane)
{
- Srt srt = toSrt(_obb.mtx);
+ const Srt srt = toSrt(_obb.mtx);
const Quaternion invRotation = invert(srt.rotation);
const Vec3 axis =
@@ -1610,7 +1720,7 @@ bool overlap(const Obb& _obb, const Plane& _plane)
bool overlap(const Obb& _obb, const Capsule& _capsule)
{
- Srt srt = toSrt(_obb.mtx);
+ const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
@@ -1629,8 +1739,10 @@ bool overlap(const Obb& _obb, const Capsule& _capsule)
bool overlap(const Obb& _obbA, const Obb& _obbB)
{
- BX_UNUSED(_obbA, _obbB);
- return false;
+ const Srt srtA = toSrt(_obbA.mtx);
+ const Srt srtB = toSrt(_obbB.mtx);
+
+ return overlap(srtA, srtB);
}
bool overlap(const Plane& _plane, const LineSegment& _line)
@@ -1699,7 +1811,7 @@ bool overlap(const Sphere& _sphere, const Plane& _plane)
bool overlap(const Sphere& _sphere, const Triangle& _triangle)
{
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _triangle);
if (!overlap(_sphere, plane) )
@@ -1737,7 +1849,7 @@ bool overlap(const Sphere& _sphere, const Disk& _disk)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
return overlap(_sphere, plane);
@@ -1807,7 +1919,7 @@ bool overlap(const Triangle& _triangleA, const Triangle& _triangleB)
template<typename Ty>
bool overlap(const Triangle& _triangle, const Ty& _ty)
{
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _triangle);
plane.normal = neg(plane.normal);
@@ -1966,7 +2078,7 @@ bool overlap(const Triangle& _triangle, const Disk& _disk)
return false;
}
- Plane plane;
+ Plane plane(init::None);
calcPlane(plane, _disk.normal, _disk.center);
return overlap(_triangle, plane);
@@ -1974,7 +2086,7 @@ bool overlap(const Triangle& _triangle, const Disk& _disk)
bool overlap(const Triangle& _triangle, const Obb& _obb)
{
- Srt srt = toSrt(_obb.mtx);
+ const Srt srt = toSrt(_obb.mtx);
Aabb aabb;
toAabb(aabb, srt.scale);
diff --git a/3rdparty/bgfx/examples/common/bounds.h b/3rdparty/bgfx/examples/common/bounds.h
index 6c8ef94057a..936a244d5d6 100644
--- a/3rdparty/bgfx/examples/common/bounds.h
+++ b/3rdparty/bgfx/examples/common/bounds.h
@@ -11,39 +11,39 @@
///
struct Aabb
{
- bx::Vec3 min;
- bx::Vec3 max;
+ bx::Vec3 min = bx::init::None;
+ bx::Vec3 max = bx::init::None;
};
///
struct Capsule
{
- bx::Vec3 pos;
- bx::Vec3 end;
+ bx::Vec3 pos = bx::init::None;
+ bx::Vec3 end = bx::init::None;
float radius;
};
///
struct Cone
{
- bx::Vec3 pos;
- bx::Vec3 end;
+ bx::Vec3 pos = bx::init::None;
+ bx::Vec3 end = bx::init::None;
float radius;
};
///
struct Cylinder
{
- bx::Vec3 pos;
- bx::Vec3 end;
+ bx::Vec3 pos = bx::init::None;
+ bx::Vec3 end = bx::init::None;
float radius;
};
///
struct Disk
{
- bx::Vec3 center;
- bx::Vec3 normal;
+ bx::Vec3 center = bx::init::None;
+ bx::Vec3 normal = bx::init::None;
float radius;
};
@@ -56,30 +56,30 @@ struct Obb
///
struct Sphere
{
- bx::Vec3 center;
+ bx::Vec3 center = bx::init::None;
float radius;
};
///
struct Triangle
{
- bx::Vec3 v0;
- bx::Vec3 v1;
- bx::Vec3 v2;
+ bx::Vec3 v0 = bx::init::None;
+ bx::Vec3 v1 = bx::init::None;
+ bx::Vec3 v2 = bx::init::None;
};
///
struct Ray
{
- bx::Vec3 pos;
- bx::Vec3 dir;
+ bx::Vec3 pos = bx::init::None;
+ bx::Vec3 dir = bx::init::None;
};
///
struct Hit
{
- bx::Vec3 pos;
- bx::Plane plane;
+ bx::Vec3 pos = bx::init::None;
+ bx::Plane plane = bx::init::None;
};
///
diff --git a/3rdparty/bgfx/examples/common/camera.cpp b/3rdparty/bgfx/examples/common/camera.cpp
index 3c154aac128..eb5ed59e82f 100644
--- a/3rdparty/bgfx/examples/common/camera.cpp
+++ b/3rdparty/bgfx/examples/common/camera.cpp
@@ -264,9 +264,9 @@ struct Camera
MouseCoords m_mouseNow;
MouseCoords m_mouseLast;
- bx::Vec3 m_eye;
- bx::Vec3 m_at;
- bx::Vec3 m_up;
+ bx::Vec3 m_eye = bx::init::Zero;
+ bx::Vec3 m_at = bx::init::Zero;
+ bx::Vec3 m_up = bx::init::Zero;
float m_horizontalAngle;
float m_verticalAngle;
diff --git a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp
index ec0c73474e1..782e3ddeba5 100644
--- a/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp
+++ b/3rdparty/bgfx/examples/common/debugdraw/debugdraw.cpp
@@ -295,30 +295,14 @@ uint32_t genSphere(uint8_t _subdiv0, void* _pos0 = NULL, uint16_t _posStride0 =
bx::Vec3 getPoint(Axis::Enum _axis, float _x, float _y)
{
- bx::Vec3 result;
-
switch (_axis)
{
- case Axis::X:
- result.x = 0.0f;
- result.y = _x;
- result.z = _y;
- break;
-
- case Axis::Y:
- result.x = _y;
- result.y = 0.0f;
- result.z = _x;
- break;
-
- default:
- result.x = _x;
- result.y = _y;
- result.z = 0.0f;
- break;
+ case Axis::X: return { 0.0f, _x, _y };
+ case Axis::Y: return { _y, 0.0f, _x };
+ default: break;
}
- return result;
+ return { _x, _y, 0.0f };
}
#include "vs_debugdraw_lines.bin.h"
@@ -1664,7 +1648,7 @@ struct DebugDrawEncoderImpl
void drawFrustum(const float* _viewProj)
{
- bx::Plane planes[6];
+ bx::Plane planes[6] = { bx::init::None, bx::init::None, bx::init::None, bx::init::None, bx::init::None, bx::init::None };
buildFrustumPlanes(planes, _viewProj);
const bx::Vec3 points[8] =
@@ -1761,8 +1745,8 @@ struct DebugDrawEncoderImpl
const float step = bx::kPi * 2.0f / num;
_weight = bx::clamp(_weight, 0.0f, 2.0f);
- bx::Vec3 udir;
- bx::Vec3 vdir;
+ bx::Vec3 udir(bx::init::None);
+ bx::Vec3 vdir(bx::init::None);
bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
float xy0[2];
@@ -1833,7 +1817,8 @@ struct DebugDrawEncoderImpl
const Attrib& attrib = m_attrib[m_stack];
if (attrib.m_wireframe)
{
- bx::Vec3 udir, vdir;
+ bx::Vec3 udir(bx::init::None);
+ bx::Vec3 vdir(bx::init::None);
bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
const float halfExtent = _size*0.5f;
@@ -1874,7 +1859,8 @@ struct DebugDrawEncoderImpl
const Attrib& attrib = m_attrib[m_stack];
- bx::Vec3 udir, vdir;
+ bx::Vec3 udir(bx::init::None);
+ bx::Vec3 vdir(bx::init::None);
bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
const Pack2D& pack = s_dds.m_sprite.get(_handle);
@@ -1994,8 +1980,8 @@ struct DebugDrawEncoderImpl
if (_thickness > 0.0f)
{
const bx::Vec3 from = { _x, _y, _z };
- bx::Vec3 mid;
- bx::Vec3 to;
+ bx::Vec3 mid(bx::init::None);
+ bx::Vec3 to(bx::init::None);
setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff);
mid = { _x + _len - _thickness, _y, _z };
@@ -2037,8 +2023,8 @@ struct DebugDrawEncoderImpl
{
const Attrib& attrib = m_attrib[m_stack];
- bx::Vec3 udir;
- bx::Vec3 vdir;
+ bx::Vec3 udir(bx::init::None);
+ bx::Vec3 vdir(bx::init::None);
bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
udir = bx::mul(udir, _step);
diff --git a/3rdparty/bgfx/examples/common/entry/dialog_darwin.mm b/3rdparty/bgfx/examples/common/entry/dialog_darwin.mm
index 97e60e5fce6..a1c2599ce5e 100644
--- a/3rdparty/bgfx/examples/common/entry/dialog_darwin.mm
+++ b/3rdparty/bgfx/examples/common/entry/dialog_darwin.mm
@@ -21,58 +21,60 @@ class Split
{
public:
Split(const bx::StringView& _str, char _ch)
- : m_str(_str)
- , m_token(_str.getPtr(), bx::strFind(_str, _ch).getPtr() )
- , m_ch(_ch)
+ : m_str(_str)
+ , m_token(_str.getPtr(), bx::strFind(_str, _ch).getPtr() )
+ , m_ch(_ch)
{
}
-
+
bx::StringView next()
{
bx::StringView result = m_token;
m_token = bx::strTrim(
- bx::StringView(m_token.getTerm()+1
- , bx::strFind(bx::StringView(m_token.getTerm()+1, m_str.getTerm() ), m_ch).getPtr() )
- , " \t\n"
- );
+ bx::StringView(m_token.getTerm()+1, bx::strFind(bx::StringView(m_token.getTerm()+1, m_str.getTerm() ), m_ch).getPtr())
+ , " \t\n"
+ );
return result;
}
-
+
bool isDone() const
{
return m_token.isEmpty();
}
-
+
private:
const bx::StringView& m_str;
bx::StringView m_token;
char m_ch;
};
-
bool openFileSelectionDialog(
- bx::FilePath& _inOutFilePath
- , FileSelectionDialogType::Enum _type
- , const bx::StringView& _title
- , const bx::StringView& _filter
- )
+ bx::FilePath& _inOutFilePath
+ , FileSelectionDialogType::Enum _type
+ , const bx::StringView& _title
+ , const bx::StringView& _filter
+ )
{
NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:10];
- bx::Error err;
-
- for (bx::LineReader lr(_filter); !lr.isDone() && err.isOk();)
+
+ for (bx::LineReader lr(_filter); !lr.isDone();)
{
const bx::StringView line = lr.next();
const bx::StringView sep = bx::strFind(line, '|');
-
+
if (!sep.isEmpty() )
{
- for (Split split(bx::strTrim(bx::StringView(sep.getPtr()+1, line.getTerm() ), " "), ' '); !split.isDone() && err.isOk();)
+ for (Split split(bx::strTrim(bx::StringView(sep.getPtr()+1, line.getTerm() ), " "), ' ')
+ ; !split.isDone()
+ ;
+ )
{
const bx::StringView token = split.next();
-
- if ( token.getLength() >= 3 && token.getPtr()[0] == '*'
- && token.getPtr()[1] == '.' && bx::isAlphaNum(token.getPtr()[2]) )
+
+ if (token.getLength() >= 3
+ && token.getPtr()[0] == '*'
+ && token.getPtr()[1] == '.'
+ && bx::isAlphaNum(token.getPtr()[2]) )
{
NSString* extension = [[NSString alloc] initWithBytes:token.getPtr()+2 length:token.getLength()-2 encoding:NSASCIIStringEncoding];
[fileTypes addObject: extension];
@@ -80,56 +82,71 @@ bool openFileSelectionDialog(
}
}
}
-
+
__block NSString* fileName = nil;
- bx::Semaphore semaphore;
- bx::Semaphore* psemaphore = &semaphore;
-
- CFRunLoopPerformBlock([[NSRunLoop mainRunLoop] getCFRunLoop],
- kCFRunLoopCommonModes,
- ^{
- NSSavePanel* panel = nil;
-
- if ( FileSelectionDialogType::Open == _type)
- {
- NSOpenPanel* openPanel = [NSOpenPanel openPanel];
- openPanel.canChooseFiles = TRUE;
- openPanel.allowsMultipleSelection = FALSE;
- openPanel.canChooseDirectories = FALSE;
- panel = openPanel;
- }
- else
- {
- panel = [NSSavePanel savePanel];
- }
-
- panel.message = [[NSString alloc] initWithBytes:_title.getPtr() length:_title.getLength() encoding:NSASCIIStringEncoding];
- panel.directoryURL = [NSURL URLWithString:@(_inOutFilePath.getCPtr())];
- panel.allowedFileTypes = fileTypes;
-
- if ([panel runModal] == NSModalResponseOK)
- {
- NSURL* url = [panel URL];
- if (nil != url)
- {
- fileName = [url path];
- [fileName retain];
- }
- }
- [panel close];
- psemaphore->post();
- });
-
- semaphore.wait();
-
- if ( fileName != nil )
+
+ void (^invokeDialog)(void) =
+ ^{
+ NSSavePanel* panel = nil;
+
+ if (FileSelectionDialogType::Open == _type)
+ {
+ NSOpenPanel* openPanel = [NSOpenPanel openPanel];
+ openPanel.canChooseFiles = TRUE;
+ openPanel.allowsMultipleSelection = FALSE;
+ openPanel.canChooseDirectories = FALSE;
+ panel = openPanel;
+ }
+ else
+ {
+ panel = [NSSavePanel savePanel];
+ }
+
+ panel.message = [[NSString alloc] initWithBytes:_title.getPtr() length:_title.getLength() encoding:NSASCIIStringEncoding];
+ panel.directoryURL = [NSURL URLWithString:@(_inOutFilePath.getCPtr())];
+ panel.allowedFileTypes = fileTypes;
+
+ if ([panel runModal] == NSModalResponseOK)
+ {
+ NSURL* url = [panel URL];
+
+ if (nil != url)
+ {
+ fileName = [url path];
+ [fileName retain];
+ }
+ }
+
+ [panel close];
+ };
+
+ if ([NSThread isMainThread])
+ {
+ invokeDialog();
+ }
+ else
+ {
+ bx::Semaphore semaphore;
+ bx::Semaphore* psemaphore = &semaphore;
+
+ CFRunLoopPerformBlock(
+ [[NSRunLoop mainRunLoop] getCFRunLoop]
+ , kCFRunLoopCommonModes
+ , ^{
+ invokeDialog();
+ psemaphore->post();
+ });
+ semaphore.wait();
+ }
+
+ if (fileName != nil)
{
_inOutFilePath.set([fileName UTF8String]);
[fileName release];
return true;
}
-
+
return false;
}
-#endif
+#endif // BX_PLATFORM_OSX
diff --git a/3rdparty/bgfx/examples/common/ps/particle_system.cpp b/3rdparty/bgfx/examples/common/ps/particle_system.cpp
index 52647d06d2f..cbcf2b874b0 100644
--- a/3rdparty/bgfx/examples/common/ps/particle_system.cpp
+++ b/3rdparty/bgfx/examples/common/ps/particle_system.cpp
@@ -248,7 +248,7 @@ namespace ps
Particle& particle = m_particles[m_num];
m_num++;
- bx::Vec3 pos;
+ bx::Vec3 pos(bx::init::None);
switch (m_shape)
{
default:
@@ -281,7 +281,7 @@ namespace ps
break;
}
- bx::Vec3 dir;
+ bx::Vec3 dir(bx::init::None);
switch (m_direction)
{
default:
diff --git a/3rdparty/bgfx/include/bgfx/bgfx.h b/3rdparty/bgfx/include/bgfx/bgfx.h
index 9af4c3a47cc..f1db8ba4ae6 100644
--- a/3rdparty/bgfx/include/bgfx/bgfx.h
+++ b/3rdparty/bgfx/include/bgfx/bgfx.h
@@ -52,6 +52,7 @@ namespace bgfx
enum Enum
{
Noop, //!< No rendering.
+ Agc, //!< AGC
Direct3D9, //!< Direct3D 9.0
Direct3D11, //!< Direct3D 11.0
Direct3D12, //!< Direct3D 12.0
diff --git a/3rdparty/bgfx/include/bgfx/c99/bgfx.h b/3rdparty/bgfx/include/bgfx/c99/bgfx.h
index 40f43e9cb34..cc03336b2fa 100644
--- a/3rdparty/bgfx/include/bgfx/c99/bgfx.h
+++ b/3rdparty/bgfx/include/bgfx/c99/bgfx.h
@@ -81,16 +81,17 @@ typedef enum bgfx_fatal
typedef enum bgfx_renderer_type
{
BGFX_RENDERER_TYPE_NOOP, /** ( 0) No rendering. */
- BGFX_RENDERER_TYPE_DIRECT3D9, /** ( 1) Direct3D 9.0 */
- BGFX_RENDERER_TYPE_DIRECT3D11, /** ( 2) Direct3D 11.0 */
- BGFX_RENDERER_TYPE_DIRECT3D12, /** ( 3) Direct3D 12.0 */
- BGFX_RENDERER_TYPE_GNM, /** ( 4) GNM */
- BGFX_RENDERER_TYPE_METAL, /** ( 5) Metal */
- BGFX_RENDERER_TYPE_NVN, /** ( 6) NVN */
- BGFX_RENDERER_TYPE_OPENGLES, /** ( 7) OpenGL ES 2.0+ */
- BGFX_RENDERER_TYPE_OPENGL, /** ( 8) OpenGL 2.1+ */
- BGFX_RENDERER_TYPE_VULKAN, /** ( 9) Vulkan */
- BGFX_RENDERER_TYPE_WEBGPU, /** (10) WebGPU */
+ BGFX_RENDERER_TYPE_AGC, /** ( 1) AGC */
+ BGFX_RENDERER_TYPE_DIRECT3D9, /** ( 2) Direct3D 9.0 */
+ BGFX_RENDERER_TYPE_DIRECT3D11, /** ( 3) Direct3D 11.0 */
+ BGFX_RENDERER_TYPE_DIRECT3D12, /** ( 4) Direct3D 12.0 */
+ BGFX_RENDERER_TYPE_GNM, /** ( 5) GNM */
+ BGFX_RENDERER_TYPE_METAL, /** ( 6) Metal */
+ BGFX_RENDERER_TYPE_NVN, /** ( 7) NVN */
+ BGFX_RENDERER_TYPE_OPENGLES, /** ( 8) OpenGL ES 2.0+ */
+ BGFX_RENDERER_TYPE_OPENGL, /** ( 9) OpenGL 2.1+ */
+ BGFX_RENDERER_TYPE_VULKAN, /** (10) Vulkan */
+ BGFX_RENDERER_TYPE_WEBGPU, /** (11) WebGPU */
BGFX_RENDERER_TYPE_COUNT
diff --git a/3rdparty/bgfx/include/bgfx/embedded_shader.h b/3rdparty/bgfx/include/bgfx/embedded_shader.h
index 311b26e584d..fa5bc20749a 100644
--- a/3rdparty/bgfx/include/bgfx/embedded_shader.h
+++ b/3rdparty/bgfx/include/bgfx/embedded_shader.h
@@ -19,114 +19,116 @@
#define BGFX_EMBEDDED_SHADER_SPIRV(...)
#define BGFX_PLATFORM_SUPPORTS_DX9BC (0 \
- || BX_PLATFORM_WINDOWS \
- )
+ || BX_PLATFORM_WINDOWS \
+ )
#define BGFX_PLATFORM_SUPPORTS_DXBC (0 \
- || BX_PLATFORM_WINDOWS \
- || BX_PLATFORM_WINRT \
- || BX_PLATFORM_XBOXONE \
- )
+ || BX_PLATFORM_WINDOWS \
+ || BX_PLATFORM_WINRT \
+ || BX_PLATFORM_XBOXONE \
+ )
#define BGFX_PLATFORM_SUPPORTS_PSSL (0 \
- || BX_PLATFORM_PS4 \
- )
+ || BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
+ )
#define BGFX_PLATFORM_SUPPORTS_ESSL (0 \
- || BX_PLATFORM_ANDROID \
- || BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_LINUX \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_RPI \
- || BX_PLATFORM_WINDOWS \
- )
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_RPI \
+ || BX_PLATFORM_WINDOWS \
+ )
#define BGFX_PLATFORM_SUPPORTS_GLSL (0 \
- || BX_PLATFORM_BSD \
- || BX_PLATFORM_LINUX \
- || BX_PLATFORM_OSX \
- || BX_PLATFORM_WINDOWS \
- )
+ || BX_PLATFORM_BSD \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_OSX \
+ || BX_PLATFORM_WINDOWS \
+ )
#define BGFX_PLATFORM_SUPPORTS_METAL (0 \
- || BX_PLATFORM_IOS \
- || BX_PLATFORM_OSX \
- )
+ || BX_PLATFORM_IOS \
+ || BX_PLATFORM_OSX \
+ )
#define BGFX_PLATFORM_SUPPORTS_NVN (0 \
- || BX_PLATFORM_NX \
- )
+ || BX_PLATFORM_NX \
+ )
#define BGFX_PLATFORM_SUPPORTS_SPIRV (0 \
- || BX_PLATFORM_ANDROID \
- || BX_PLATFORM_EMSCRIPTEN \
- || BX_PLATFORM_LINUX \
- || BX_PLATFORM_WINDOWS \
- || BX_PLATFORM_OSX \
- )
+ || BX_PLATFORM_ANDROID \
+ || BX_PLATFORM_EMSCRIPTEN \
+ || BX_PLATFORM_LINUX \
+ || BX_PLATFORM_WINDOWS \
+ || BX_PLATFORM_OSX \
+ )
#if BGFX_PLATFORM_SUPPORTS_DX9BC
# undef BGFX_EMBEDDED_SHADER_DX9BC
# define BGFX_EMBEDDED_SHADER_DX9BC(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _dx9 ), BX_COUNTOF(BX_CONCATENATE(_name, _dx9 ) ) },
+ { _renderer, BX_CONCATENATE(_name, _dx9 ), BX_COUNTOF(BX_CONCATENATE(_name, _dx9 ) ) },
#endif // BGFX_PLATFORM_SUPPORTS_DX9BC
#if BGFX_PLATFORM_SUPPORTS_DXBC
# undef BGFX_EMBEDDED_SHADER_DXBC
# define BGFX_EMBEDDED_SHADER_DXBC(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _dx11), BX_COUNTOF(BX_CONCATENATE(_name, _dx11) ) },
+ { _renderer, BX_CONCATENATE(_name, _dx11), BX_COUNTOF(BX_CONCATENATE(_name, _dx11) ) },
#endif // BGFX_PLATFORM_SUPPORTS_DXBC
#if BGFX_PLATFORM_SUPPORTS_PSSL
# undef BGFX_EMBEDDED_SHADER_PSSL
# define BGFX_EMBEDDED_SHADER_PSSL(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _pssl), BX_CONCATENATE(_name, _pssl_size) },
+ { _renderer, BX_CONCATENATE(_name, _pssl), BX_CONCATENATE(_name, _pssl_size) },
#endif // BGFX_PLATFORM_SUPPORTS_PSSL
#if BGFX_PLATFORM_SUPPORTS_ESSL
# undef BGFX_EMBEDDED_SHADER_ESSL
# define BGFX_EMBEDDED_SHADER_ESSL(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _essl), BX_COUNTOF(BX_CONCATENATE(_name, _essl) ) },
+ { _renderer, BX_CONCATENATE(_name, _essl), BX_COUNTOF(BX_CONCATENATE(_name, _essl) ) },
#endif // BGFX_PLATFORM_SUPPORTS_ESSL
#if BGFX_PLATFORM_SUPPORTS_GLSL
# undef BGFX_EMBEDDED_SHADER_GLSL
# define BGFX_EMBEDDED_SHADER_GLSL(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _glsl), BX_COUNTOF(BX_CONCATENATE(_name, _glsl) ) },
+ { _renderer, BX_CONCATENATE(_name, _glsl), BX_COUNTOF(BX_CONCATENATE(_name, _glsl) ) },
#endif // BGFX_PLATFORM_SUPPORTS_GLSL
#if BGFX_PLATFORM_SUPPORTS_SPIRV
# undef BGFX_EMBEDDED_SHADER_SPIRV
# define BGFX_EMBEDDED_SHADER_SPIRV(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _spv), BX_COUNTOF(BX_CONCATENATE(_name, _spv) ) },
+ { _renderer, BX_CONCATENATE(_name, _spv), BX_COUNTOF(BX_CONCATENATE(_name, _spv) ) },
#endif // BGFX_PLATFORM_SUPPORTS_SPIRV
#if BGFX_PLATFORM_SUPPORTS_METAL
# undef BGFX_EMBEDDED_SHADER_METAL
# define BGFX_EMBEDDED_SHADER_METAL(_renderer, _name) \
- { _renderer, BX_CONCATENATE(_name, _mtl), BX_COUNTOF(BX_CONCATENATE(_name, _mtl) ) },
+ { _renderer, BX_CONCATENATE(_name, _mtl), BX_COUNTOF(BX_CONCATENATE(_name, _mtl) ) },
#endif // BGFX_PLATFORM_SUPPORTS_METAL
-#define BGFX_EMBEDDED_SHADER(_name) \
- { \
- #_name, \
- { \
- BGFX_EMBEDDED_SHADER_DX9BC(bgfx::RendererType::Direct3D9, _name) \
- BGFX_EMBEDDED_SHADER_DXBC (bgfx::RendererType::Direct3D11, _name) \
- BGFX_EMBEDDED_SHADER_DXBC (bgfx::RendererType::Direct3D12, _name) \
- BGFX_EMBEDDED_SHADER_PSSL (bgfx::RendererType::Gnm, _name) \
- BGFX_EMBEDDED_SHADER_METAL(bgfx::RendererType::Metal, _name) \
- BGFX_EMBEDDED_SHADER_NVN (bgfx::RendererType::Nvn, _name) \
- BGFX_EMBEDDED_SHADER_ESSL (bgfx::RendererType::OpenGLES, _name) \
- BGFX_EMBEDDED_SHADER_GLSL (bgfx::RendererType::OpenGL, _name) \
- BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::Vulkan, _name) \
- BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::WebGPU, _name) \
- { bgfx::RendererType::Noop, (const uint8_t*)"VSH\x5\x0\x0\x0\x0\x0\x0", 10 }, \
- { bgfx::RendererType::Count, NULL, 0 } \
- } \
- }
-
-#define BGFX_EMBEDDED_SHADER_END() \
- { \
- NULL, \
- { \
- { bgfx::RendererType::Count, NULL, 0 } \
- } \
- }
+#define BGFX_EMBEDDED_SHADER(_name) \
+ { \
+ #_name, \
+ { \
+ BGFX_EMBEDDED_SHADER_PSSL (bgfx::RendererType::Agc, _name) \
+ BGFX_EMBEDDED_SHADER_DX9BC(bgfx::RendererType::Direct3D9, _name) \
+ BGFX_EMBEDDED_SHADER_DXBC (bgfx::RendererType::Direct3D11, _name) \
+ BGFX_EMBEDDED_SHADER_DXBC (bgfx::RendererType::Direct3D12, _name) \
+ BGFX_EMBEDDED_SHADER_PSSL (bgfx::RendererType::Gnm, _name) \
+ BGFX_EMBEDDED_SHADER_METAL(bgfx::RendererType::Metal, _name) \
+ BGFX_EMBEDDED_SHADER_NVN (bgfx::RendererType::Nvn, _name) \
+ BGFX_EMBEDDED_SHADER_ESSL (bgfx::RendererType::OpenGLES, _name) \
+ BGFX_EMBEDDED_SHADER_GLSL (bgfx::RendererType::OpenGL, _name) \
+ BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::Vulkan, _name) \
+ BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::WebGPU, _name) \
+ { bgfx::RendererType::Noop, (const uint8_t*)"VSH\x5\x0\x0\x0\x0\x0\x0", 10 }, \
+ { bgfx::RendererType::Count, NULL, 0 } \
+ } \
+ }
+
+#define BGFX_EMBEDDED_SHADER_END() \
+ { \
+ NULL, \
+ { \
+ { bgfx::RendererType::Count, NULL, 0 } \
+ } \
+ }
namespace bgfx
{
diff --git a/3rdparty/bgfx/scripts/bgfx.idl b/3rdparty/bgfx/scripts/bgfx.idl
index c0c094cb821..54647f6a66e 100644
--- a/3rdparty/bgfx/scripts/bgfx.idl
+++ b/3rdparty/bgfx/scripts/bgfx.idl
@@ -450,6 +450,7 @@ enum.Fatal { underscore, comment = "" }
--- Renderer backend type enum.
enum.RendererType { comment = "Renderer types:" }
.Noop --- No rendering.
+ .Agc --- AGC
.Direct3D9 --- Direct3D 9.0
.Direct3D11 --- Direct3D 11.0
.Direct3D12 --- Direct3D 12.0
@@ -610,6 +611,7 @@ enum.UniformType { comment = "Uniform types:" }
.Vec4 --- 4 floats vector.
.Mat3 --- 3x3 matrix.
.Mat4 --- 4x4 matrix.
+ ()
--- Backbuffer ratio enum.
enum.BackbufferRatio { comment = "Backbuffer ratios:" }
@@ -619,12 +621,14 @@ enum.BackbufferRatio { comment = "Backbuffer ratios:" }
.Eighth --- One eighth size of backbuffer.
.Sixteenth --- One sixteenth size of backbuffer.
.Double --- Double size of backbuffer.
+ ()
--- Occlusion query result.
enum.OcclusionQueryResult { comment = "Occlusion query results:" }
.Invisible --- Query failed test.
.Visible --- Query passed test.
.NoResult --- Query result is not available yet.
+ ()
--- Primitive topology.
enum.Topology { underscore, comment = "Primitive topology:" }
@@ -633,6 +637,7 @@ enum.Topology { underscore, comment = "Primitive topology:" }
.LineList --- Line list.
.LineStrip --- Line strip.
.PointList --- Point list.
+ ()
--- Topology conversion function.
enum.TopologyConvert { underscore , comment = "Topology conversion functions:" }
@@ -641,6 +646,7 @@ enum.TopologyConvert { underscore , comment = "Topology conversion functions:" }
.TriListToLineList --- Convert triangle list to line list.
.TriStripToTriList --- Convert triangle strip to triangle list.
.LineStripToLineList --- Convert line strip to line list.
+ ()
--- Topology sort order.
enum.TopologySort { underscore, comment = "Topology sort order:" , }
@@ -664,6 +670,7 @@ enum.ViewMode { underscore, comment = "View modes:" }
.Sequential --- Sort in the same order in which submit calls were called.
.DepthAscending --- Sort draw call depth in ascending order.
.DepthDescending --- Sort draw call depth in descending order.
+ ()
--- Render frame enum.
enum.RenderFrame { underscore, comment = "" }
diff --git a/3rdparty/bgfx/scripts/bgfx.lua b/3rdparty/bgfx/scripts/bgfx.lua
index 0fba9be0a3c..7f176a2e24a 100644
--- a/3rdparty/bgfx/scripts/bgfx.lua
+++ b/3rdparty/bgfx/scripts/bgfx.lua
@@ -171,6 +171,11 @@ function bgfxProjectBase(_kind, _defines)
path.join(BGFX_DIR, "src/**.bin.h"),
}
+ overridefiles(BGFX_DIR, path.join(BGFX_DIR, "../bgfx-agc"), {
+ path.join(BGFX_DIR, "src/renderer_agc.cpp"),
+ path.join(BGFX_DIR, "src/renderer_agc.h"),
+ })
+
overridefiles(BGFX_DIR, path.join(BGFX_DIR, "../bgfx-gnm"), {
path.join(BGFX_DIR, "src/renderer_gnm.cpp"),
path.join(BGFX_DIR, "src/renderer_gnm.h"),
diff --git a/3rdparty/bgfx/src/amalgamated.cpp b/3rdparty/bgfx/src/amalgamated.cpp
index 3c6f067c59f..60c8b1f21cd 100644
--- a/3rdparty/bgfx/src/amalgamated.cpp
+++ b/3rdparty/bgfx/src/amalgamated.cpp
@@ -11,6 +11,7 @@
#include "glcontext_wgl.cpp"
#include "glcontext_html5.cpp"
#include "nvapi.cpp"
+#include "renderer_agc.cpp"
#include "renderer_d3d11.cpp"
#include "renderer_d3d12.cpp"
#include "renderer_d3d9.cpp"
diff --git a/3rdparty/bgfx/src/bgfx.cpp b/3rdparty/bgfx/src/bgfx.cpp
index af96b5f3703..a2d52b6b83d 100644
--- a/3rdparty/bgfx/src/bgfx.cpp
+++ b/3rdparty/bgfx/src/bgfx.cpp
@@ -18,6 +18,7 @@
BX_ERROR_RESULT(BGFX_ERROR_TEXTURE_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 1) );
BX_ERROR_RESULT(BGFX_ERROR_FRAME_BUFFER_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 2) );
+BX_ERROR_RESULT(BGFX_ERROR_IDENTIFIER_VALIDATION, BX_MAKEFOURCC('b', 'g', 0, 3) );
namespace bgfx
{
@@ -973,7 +974,7 @@ namespace bgfx
return s_predefinedName[_enum];
}
- PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name)
+ PredefinedUniform::Enum nameToPredefinedUniformEnum(const bx::StringView& _name)
{
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
{
@@ -2584,6 +2585,7 @@ namespace bgfx
}
BGFX_RENDERER_CONTEXT(noop);
+ BGFX_RENDERER_CONTEXT(agc);
BGFX_RENDERER_CONTEXT(d3d9);
BGFX_RENDERER_CONTEXT(d3d11);
BGFX_RENDERER_CONTEXT(d3d12);
@@ -2607,6 +2609,7 @@ namespace bgfx
static RendererCreator s_rendererCreator[] =
{
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, true }, // Noop
+ { agc::rendererCreate, agc::rendererDestroy, BGFX_RENDERER_AGC_NAME, !!BGFX_CONFIG_RENDERER_AGC }, // GNM
{ d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
{ d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
{ d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
@@ -4234,7 +4237,14 @@ namespace bgfx
BX_ASSERT(0 < _num, "Requesting 0 vertices.");
BX_ASSERT(isValid(_layout), "Invalid VertexLayout.");
- s_ctx->allocTransientVertexBuffer(_tvb, _num, _layout);
+ VertexLayoutHandle layoutHandle;
+ {
+ BGFX_MUTEX_SCOPE(s_ctx->m_resourceApiLock);
+ layoutHandle = s_ctx->findOrCreateVertexLayout(_layout, true);
+ }
+ BX_ASSERT(isValid(layoutHandle), "Failed to allocate vertex layout handle (BGFX_CONFIG_MAX_VERTEX_LAYOUTS, max: %d).", BGFX_CONFIG_MAX_VERTEX_LAYOUTS);
+
+ s_ctx->allocTransientVertexBuffer(_tvb, _num, layoutHandle, _layout.m_stride);
BX_ASSERT(_num == _tvb->size / _layout.m_stride
, "Failed to allocate transient vertex buffer (requested %d, available %d). "
@@ -4635,6 +4645,55 @@ namespace bgfx
return err.isOk();
}
+ void isIdentifierValid(const bx::StringView& _name, bx::Error* _err)
+ {
+ BX_ERROR_SCOPE(_err, "Uniform identifier validation");
+
+ BGFX_ERROR_CHECK(false
+ || !_name.isEmpty()
+ , _err
+ , BGFX_ERROR_IDENTIFIER_VALIDATION
+ , "Identifier can't be empty."
+ , ""
+ );
+
+ BGFX_ERROR_CHECK(false
+ || PredefinedUniform::Count == nameToPredefinedUniformEnum(_name)
+ , _err
+ , BGFX_ERROR_IDENTIFIER_VALIDATION
+ , "Identifier can't use predefined uniform name."
+ , ""
+ );
+
+ const char ch = *_name.getPtr();
+ BGFX_ERROR_CHECK(false
+ || bx::isAlpha(ch)
+ || '_' == ch
+ , _err
+ , BGFX_ERROR_IDENTIFIER_VALIDATION
+ , "The first character of an identifier should be either an alphabet character or an underscore."
+ , ""
+ );
+
+ bool result = true;
+
+ for (const char* ptr = _name.getPtr() + 1, *term = _name.getTerm()
+ ; ptr != term && result
+ ; ++ptr
+ )
+ {
+ result &= bx::isAlphaNum(*ptr) || '_' == *ptr;
+ }
+
+ BGFX_ERROR_CHECK(false
+ || result
+ , _err
+ , BGFX_ERROR_IDENTIFIER_VALIDATION
+ , "Identifier contains invalid characters. Identifier must be the alphabet character, number, or underscore."
+ , ""
+ );
+ }
+
void calcTextureSize(TextureInfo& _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, TextureFormat::Enum _format)
{
bimg::imageGetSize( (bimg::TextureInfo*)&_info, _width, _height, _depth, _cubeMap, _hasMips, _numLayers, bimg::TextureFormat::Enum(_format) );
diff --git a/3rdparty/bgfx/src/bgfx_p.h b/3rdparty/bgfx/src/bgfx_p.h
index ab5a6bb8329..e75d07a3a37 100644
--- a/3rdparty/bgfx/src/bgfx_p.h
+++ b/3rdparty/bgfx/src/bgfx_p.h
@@ -67,7 +67,7 @@
namespace bgfx
{
#if BX_COMPILER_CLANG_ANALYZER
- void __attribute__( (analyzer_noreturn) ) fatal(Fatal::Enum _code, const char* _format, ...);
+ void __attribute__( (analyzer_noreturn) ) fatal(const char* _filePath, uint16_t _line, Fatal::Enum _code, const char* _format, ...);
#else
void fatal(const char* _filePath, uint16_t _line, Fatal::Enum _code, const char* _format, ...);
#endif // BX_COMPILER_CLANG_ANALYZER
@@ -245,6 +245,8 @@ namespace stl = std;
#define BGFX_SUBMIT_INTERNAL_OCCLUSION_VISIBLE UINT8_C(0x80)
#define BGFX_SUBMIT_INTERNAL_RESERVED_MASK UINT8_C(0xff)
+#define BGFX_RENDERER_NOOP_NAME "Noop"
+#define BGFX_RENDERER_AGC_NAME "AGC"
#define BGFX_RENDERER_DIRECT3D9_NAME "Direct3D 9"
#define BGFX_RENDERER_DIRECT3D11_NAME "Direct3D 11"
#define BGFX_RENDERER_DIRECT3D12_NAME "Direct3D 12"
@@ -253,7 +255,6 @@ namespace stl = std;
#define BGFX_RENDERER_NVN_NAME "NVN"
#define BGFX_RENDERER_VULKAN_NAME "Vulkan"
#define BGFX_RENDERER_WEBGPU_NAME "WebGPU"
-#define BGFX_RENDERER_NOOP_NAME "Noop"
#if BGFX_CONFIG_RENDERER_OPENGL
# if BGFX_CONFIG_RENDERER_OPENGL >= 31 && BGFX_CONFIG_RENDERER_OPENGL <= 33
@@ -303,6 +304,7 @@ namespace bgfx
extern PlatformData g_platformData;
extern bool g_platformDataChangedSinceReset;
extern void isFrameBufferValid(uint8_t _num, const Attachment* _attachment, bx::Error* _err);
+ extern void isIdentifierValid(const bx::StringView& _name, bx::Error* _err);
#if BGFX_CONFIG_MAX_DRAW_CALLS < (64<<10)
typedef uint16_t RenderItemCount;
@@ -791,7 +793,7 @@ namespace bgfx
const char* getUniformTypeName(UniformType::Enum _enum);
UniformType::Enum nameToUniformTypeEnum(const char* _name);
const char* getPredefinedUniformName(PredefinedUniform::Enum _enum);
- PredefinedUniform::Enum nameToPredefinedUniformEnum(const char* _name);
+ PredefinedUniform::Enum nameToPredefinedUniformEnum(const bx::StringView& _name);
class CommandBuffer
{
@@ -3194,21 +3196,29 @@ namespace bgfx
cmdbuf.write(_handle);
}
- VertexLayoutHandle findVertexLayout(const VertexLayout& _layout)
+ VertexLayoutHandle findOrCreateVertexLayout(const VertexLayout& _layout, bool _refCountOnCreation = false)
{
VertexLayoutHandle layoutHandle = m_vertexLayoutRef.find(_layout.m_hash);
+ if (isValid(layoutHandle) )
+ {
+ return layoutHandle;
+ }
+
+ layoutHandle = { m_layoutHandle.alloc() };
if (!isValid(layoutHandle) )
{
- layoutHandle.idx = m_layoutHandle.alloc();
- if (!isValid(layoutHandle) )
- {
- return layoutHandle;
- }
+ BX_TRACE("WARNING: Failed to allocate vertex layout handle (BGFX_CONFIG_MAX_VERTEX_LAYOUTS, max: %d).", BGFX_CONFIG_MAX_VERTEX_LAYOUTS);
+ return BGFX_INVALID_HANDLE;
+ }
- CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexLayout);
- cmdbuf.write(layoutHandle);
- cmdbuf.write(_layout);
+ CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexLayout);
+ cmdbuf.write(layoutHandle);
+ cmdbuf.write(_layout);
+
+ if (_refCountOnCreation)
+ {
+ m_vertexLayoutRef.add(layoutHandle, _layout.m_hash);
}
return layoutHandle;
@@ -3218,10 +3228,9 @@ namespace bgfx
{
BGFX_MUTEX_SCOPE(m_resourceApiLock);
- VertexLayoutHandle handle = findVertexLayout(_layout);
+ VertexLayoutHandle handle = findOrCreateVertexLayout(_layout);
if (!isValid(handle) )
{
- BX_TRACE("WARNING: Failed to allocate vertex layout handle (BGFX_CONFIG_MAX_VERTEX_LAYOUTS, max: %d).", BGFX_CONFIG_MAX_VERTEX_LAYOUTS);
return BGFX_INVALID_HANDLE;
}
@@ -3247,7 +3256,7 @@ namespace bgfx
if (isValid(handle) )
{
- VertexLayoutHandle layoutHandle = findVertexLayout(_layout);
+ VertexLayoutHandle layoutHandle = findOrCreateVertexLayout(_layout);
if (!isValid(layoutHandle) )
{
BX_TRACE("WARNING: Failed to allocate vertex layout handle (BGFX_CONFIG_MAX_VERTEX_LAYOUTS, max: %d).", BGFX_CONFIG_MAX_VERTEX_LAYOUTS);
@@ -3557,7 +3566,7 @@ namespace bgfx
{
BGFX_MUTEX_SCOPE(m_resourceApiLock);
- VertexLayoutHandle layoutHandle = findVertexLayout(_layout);
+ VertexLayoutHandle layoutHandle = findOrCreateVertexLayout(_layout);
if (!isValid(layoutHandle) )
{
BX_TRACE("WARNING: Failed to allocate vertex layout handle (BGFX_CONFIG_MAX_VERTEX_LAYOUTS, max: %d).", BGFX_CONFIG_MAX_VERTEX_LAYOUTS);
@@ -3790,7 +3799,7 @@ namespace bgfx
if (NULL != _layout)
{
- layoutHandle = findVertexLayout(*_layout);
+ layoutHandle = findOrCreateVertexLayout(*_layout);
m_vertexLayoutRef.add(handle, layoutHandle, _layout->m_hash);
stride = _layout->m_stride;
@@ -3829,32 +3838,19 @@ namespace bgfx
BX_ALIGNED_FREE(g_allocator, _tvb, 16);
}
- BGFX_API_FUNC(void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, const VertexLayout& _layout) )
+ BGFX_API_FUNC(void allocTransientVertexBuffer(TransientVertexBuffer* _tvb, uint32_t _num, VertexLayoutHandle _layoutHandle, uint16_t _stride) )
{
BGFX_MUTEX_SCOPE(m_resourceApiLock);
- VertexLayoutHandle layoutHandle = m_vertexLayoutRef.find(_layout.m_hash);
-
- TransientVertexBuffer& dvb = *m_submit->m_transientVb;
-
- if (!isValid(layoutHandle) )
- {
- VertexLayoutHandle temp = { m_layoutHandle.alloc() };
- layoutHandle = temp;
- CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateVertexLayout);
- cmdbuf.write(layoutHandle);
- cmdbuf.write(_layout);
- m_vertexLayoutRef.add(layoutHandle, _layout.m_hash);
- }
-
- uint32_t offset = m_submit->allocTransientVertexBuffer(_num, _layout.m_stride);
+ const uint32_t offset = m_submit->allocTransientVertexBuffer(_num, _stride);
+ const TransientVertexBuffer& dvb = *m_submit->m_transientVb;
- _tvb->data = &dvb.data[offset];
- _tvb->size = _num * _layout.m_stride;
- _tvb->startVertex = bx::strideAlign(offset, _layout.m_stride)/_layout.m_stride;
- _tvb->stride = _layout.m_stride;
- _tvb->handle = dvb.handle;
- _tvb->layoutHandle = layoutHandle;
+ _tvb->data = &dvb.data[offset];
+ _tvb->size = _num * _stride;
+ _tvb->startVertex = bx::strideAlign(offset, _stride)/_stride;
+ _tvb->stride = _stride;
+ _tvb->handle = dvb.handle;
+ _tvb->layoutHandle = _layoutHandle;
}
BGFX_API_FUNC(void allocInstanceDataBuffer(InstanceDataBuffer* _idb, uint32_t _num, uint16_t _stride) )
@@ -4697,10 +4693,15 @@ namespace bgfx
{
BGFX_MUTEX_SCOPE(m_resourceApiLock);
- if (PredefinedUniform::Count != nameToPredefinedUniformEnum(_name) )
{
- BX_TRACE("%s is predefined uniform name.", _name);
- return BGFX_INVALID_HANDLE;
+ bx::Error err;
+ isIdentifierValid(_name, &err);
+ BGFX_ERROR_ASSERT(&err);
+
+ if (!err.isOk() )
+ {
+ return BGFX_INVALID_HANDLE;
+ }
}
_num = bx::max<uint16_t>(1, _num);
diff --git a/3rdparty/bgfx/src/bgfx_shader.sh b/3rdparty/bgfx/src/bgfx_shader.sh
index 15cee368bf3..45c59775bc6 100644
--- a/3rdparty/bgfx/src/bgfx_shader.sh
+++ b/3rdparty/bgfx/src/bgfx_shader.sh
@@ -315,17 +315,55 @@ vec2 bgfxTextureSize(BgfxUSampler2D _sampler, int _lod)
return result;
}
-vec4 bgfxTextureGather(BgfxSampler2D _sampler, vec2 _coord)
+vec4 bgfxTextureGather0(BgfxSampler2D _sampler, vec2 _coord)
{
- return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord );
+ return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
}
-vec4 bgfxTextureGatherOffset(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
+vec4 bgfxTextureGather1(BgfxSampler2D _sampler, vec2 _coord)
{
- return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord, _offset );
+ return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
}
-vec4 bgfxTextureGather(BgfxSampler2DArray _sampler, vec3 _coord)
+vec4 bgfxTextureGather2(BgfxSampler2D _sampler, vec2 _coord)
{
- return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord );
+ return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
+}
+vec4 bgfxTextureGather3(BgfxSampler2D _sampler, vec2 _coord)
+{
+ return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
+}
+
+vec4 bgfxTextureGatherOffset0(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
+{
+ return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord, _offset);
+}
+vec4 bgfxTextureGatherOffset1(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
+{
+ return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord, _offset);
+}
+vec4 bgfxTextureGatherOffset2(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
+{
+ return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord, _offset);
+}
+vec4 bgfxTextureGatherOffset3(BgfxSampler2D _sampler, vec2 _coord, ivec2 _offset)
+{
+ return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord, _offset);
+}
+
+vec4 bgfxTextureGather0(BgfxSampler2DArray _sampler, vec3 _coord)
+{
+ return _sampler.m_texture.GatherRed(_sampler.m_sampler, _coord);
+}
+vec4 bgfxTextureGather1(BgfxSampler2DArray _sampler, vec3 _coord)
+{
+ return _sampler.m_texture.GatherGreen(_sampler.m_sampler, _coord);
+}
+vec4 bgfxTextureGather2(BgfxSampler2DArray _sampler, vec3 _coord)
+{
+ return _sampler.m_texture.GatherBlue(_sampler.m_sampler, _coord);
+}
+vec4 bgfxTextureGather3(BgfxSampler2DArray _sampler, vec3 _coord)
+{
+ return _sampler.m_texture.GatherAlpha(_sampler.m_sampler, _coord);
}
ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod)
@@ -440,8 +478,8 @@ vec3 bgfxTextureSize(BgfxSampler3D _sampler, int _lod)
# define texelFetch(_sampler, _coord, _lod) bgfxTexelFetch(_sampler, _coord, _lod)
# define texelFetchOffset(_sampler, _coord, _lod, _offset) bgfxTexelFetchOffset(_sampler, _coord, _lod, _offset)
# define textureSize(_sampler, _lod) bgfxTextureSize(_sampler, _lod)
-# define textureGather(_sampler, _coord) bgfxTextureGather(_sampler, _coord)
-# define textureGatherOffset(_sampler, _coord, _offset) bgfxTextureGatherOffset(_sampler, _coord, _offset)
+# define textureGather(_sampler, _coord, _comp) bgfxTextureGather ## _comp(_sampler, _coord)
+# define textureGatherOffset(_sampler, _coord, _offset, _comp) bgfxTextureGatherOffset ## _comp(_sampler, _coord, _offset)
# else
# define sampler2DShadow sampler2D
diff --git a/3rdparty/bgfx/src/config.h b/3rdparty/bgfx/src/config.h
index c744decf363..1566b321c1b 100644
--- a/3rdparty/bgfx/src/config.h
+++ b/3rdparty/bgfx/src/config.h
@@ -19,7 +19,8 @@
# define BGFX_CONFIG_DEBUG 0
#endif // BGFX_CONFIG_DEBUG
-#if !defined(BGFX_CONFIG_RENDERER_DIRECT3D9) \
+#if !defined(BGFX_CONFIG_RENDERER_AGC) \
+ && !defined(BGFX_CONFIG_RENDERER_DIRECT3D9) \
&& !defined(BGFX_CONFIG_RENDERER_DIRECT3D11) \
&& !defined(BGFX_CONFIG_RENDERER_DIRECT3D12) \
&& !defined(BGFX_CONFIG_RENDERER_GNM) \
@@ -30,6 +31,12 @@
&& !defined(BGFX_CONFIG_RENDERER_VULKAN) \
&& !defined(BGFX_CONFIG_RENDERER_WEBGPU)
+# ifndef BGFX_CONFIG_RENDERER_AGC
+# define BGFX_CONFIG_RENDERER_AGC (0 \
+ || BX_PLATFORM_PS5 \
+ ? 1 : 0)
+# endif // BGFX_CONFIG_RENDERER_AGC
+
# ifndef BGFX_CONFIG_RENDERER_DIRECT3D9
# define BGFX_CONFIG_RENDERER_DIRECT3D9 (0 \
|| BX_PLATFORM_WINDOWS \
@@ -116,6 +123,10 @@
# endif // BGFX_CONFIG_RENDERER_WEBGPU
#else
+# ifndef BGFX_CONFIG_RENDERER_AGC
+# define BGFX_CONFIG_RENDERER_AGC 0
+# endif // BGFX_CONFIG_RENDERER_AGC
+
# ifndef BGFX_CONFIG_RENDERER_DIRECT3D9
# define BGFX_CONFIG_RENDERER_DIRECT3D9 0
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9
diff --git a/3rdparty/bgfx/src/dxgi.cpp b/3rdparty/bgfx/src/dxgi.cpp
index 05d77519a27..34c3e69ce29 100644
--- a/3rdparty/bgfx/src/dxgi.cpp
+++ b/3rdparty/bgfx/src/dxgi.cpp
@@ -122,6 +122,7 @@ namespace bgfx
, m_factory(NULL)
, m_adapter(NULL)
, m_output(NULL)
+ , m_tearingSupported(false)
{
}
@@ -389,6 +390,8 @@ namespace bgfx
: 0
;
+ m_tearingSupported = allowTearing;
+
DX_RELEASE_I(factory5);
}
@@ -785,6 +788,11 @@ namespace bgfx
#endif // BX_PLATFORM_WINDOWS || BX_PLATFORM_WINRT
}
+ bool Dxgi::tearingSupported() const
+ {
+ return m_tearingSupported;
+ }
+
} // namespace bgfx
#endif // BGFX_CONFIG_RENDERER_DIRECT3D11 || BGFX_CONFIG_RENDERER_DIRECT3D12
diff --git a/3rdparty/bgfx/src/dxgi.h b/3rdparty/bgfx/src/dxgi.h
index b49439ad7c1..43671bf17e2 100644
--- a/3rdparty/bgfx/src/dxgi.h
+++ b/3rdparty/bgfx/src/dxgi.h
@@ -100,6 +100,9 @@ namespace bgfx
void trim();
///
+ bool tearingSupported() const;
+
+ ///
void* m_dxgiDll;
void* m_dxgiDebugDll;
@@ -108,6 +111,7 @@ namespace bgfx
FactoryI* m_factory;
AdapterI* m_adapter;
OutputI* m_output;
+ bool m_tearingSupported;
};
} // namespace bgfx
diff --git a/3rdparty/bgfx/src/renderer_agc.cpp b/3rdparty/bgfx/src/renderer_agc.cpp
new file mode 100644
index 00000000000..f1e41f98e69
--- /dev/null
+++ b/3rdparty/bgfx/src/renderer_agc.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2011-2021 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#include "bgfx_p.h"
+
+namespace bgfx { namespace agc
+{
+ RendererContextI* rendererCreate(const Init& _init)
+ {
+ BX_UNUSED(_init);
+ return NULL;
+ }
+
+ void rendererDestroy()
+ {
+ }
+
+} /* namespace agc */ } // namespace bgfx
diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp
index 8c709409497..e936d64ae12 100644
--- a/3rdparty/bgfx/src/renderer_d3d11.cpp
+++ b/3rdparty/bgfx/src/renderer_d3d11.cpp
@@ -2287,7 +2287,15 @@ namespace bgfx { namespace d3d11
if (NULL != m_swapChain
&& m_needPresent)
{
- hr = m_swapChain->Present(syncInterval, 0);
+ uint32_t presentFlags = 0;
+
+ if (!syncInterval
+ && m_dxgi.tearingSupported() )
+ {
+ presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
+ }
+
+ hr = m_swapChain->Present(syncInterval, presentFlags);
m_needPresent = false;
}
@@ -2968,11 +2976,12 @@ namespace bgfx { namespace d3d11
const uint32_t index = (_flags & BGFX_SAMPLER_BORDER_COLOR_MASK) >> BGFX_SAMPLER_BORDER_COLOR_SHIFT;
_flags &= BGFX_SAMPLER_BITS_MASK;
- // Force both min+max anisotropic, can't be set individually.
- _flags |= 0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC) )
- ? BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC
- : 0
- ;
+ // Force min+mag anisotropic (can't be set individually) and remove mip (not supported).
+ if (0 != (_flags & (BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC)))
+ {
+ _flags |= BGFX_SAMPLER_MIN_ANISOTROPIC|BGFX_SAMPLER_MAG_ANISOTROPIC;
+ _flags &= ~BGFX_SAMPLER_MIP_MASK;
+ }
uint32_t hash;
ID3D11SamplerState* sampler;
@@ -3033,7 +3042,7 @@ namespace bgfx { namespace d3d11
sd.MinLOD = 0;
sd.MaxLOD = D3D11_FLOAT32_MAX;
- m_device->CreateSamplerState(&sd, &sampler);
+ DX_CHECK(m_device->CreateSamplerState(&sd, &sampler));
DX_CHECK_REFCOUNT(sampler, 1);
m_samplerStateCache.add(hash, sampler);
@@ -3367,18 +3376,10 @@ namespace bgfx { namespace d3d11
data = (const char*)m_uniforms[handle.idx];
}
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
- case UniformType::_uniform: \
- case UniformType::_uniform|kUniformFragmentBit: \
- { \
- setShaderUniform(uint8_t(type), loc, data, num); \
- } \
- break;
-
switch ( (uint32_t)type)
{
case UniformType::Mat3:
- case UniformType::Mat3|kUniformFragmentBit: \
+ case UniformType::Mat3|kUniformFragmentBit:
{
float* value = (float*)data;
for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9)
@@ -3401,9 +3402,16 @@ namespace bgfx { namespace d3d11
}
break;
- CASE_IMPLEMENT_UNIFORM(Sampler, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, F, float);
- CASE_IMPLEMENT_UNIFORM(Mat4, F, float);
+ case UniformType::Sampler:
+ case UniformType::Sampler | kUniformFragmentBit:
+ case UniformType::Vec4:
+ case UniformType::Vec4 | kUniformFragmentBit:
+ case UniformType::Mat4:
+ case UniformType::Mat4 | kUniformFragmentBit:
+ {
+ setShaderUniform(uint8_t(type), loc, data, num);
+ }
+ break;
case UniformType::End:
break;
@@ -3412,7 +3420,6 @@ namespace bgfx { namespace d3d11
BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
-#undef CASE_IMPLEMENT_UNIFORM
}
}
diff --git a/3rdparty/bgfx/src/renderer_d3d12.cpp b/3rdparty/bgfx/src/renderer_d3d12.cpp
index 6dec7b34249..ebb072f785c 100644
--- a/3rdparty/bgfx/src/renderer_d3d12.cpp
+++ b/3rdparty/bgfx/src/renderer_d3d12.cpp
@@ -1508,17 +1508,26 @@ namespace bgfx { namespace d3d12
HRESULT hr = S_OK;
uint32_t syncInterval = !!(m_resolution.reset & BGFX_RESET_VSYNC);
- uint32_t flags = 0 == syncInterval ? DXGI_PRESENT_RESTART : 0;
+ uint32_t presentFlags = 0;
+ if (syncInterval)
+ {
+ presentFlags |= DXGI_PRESENT_RESTART;
+ }
+ else if (m_dxgi.tearingSupported() )
+ {
+ presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
+ }
+
for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii)
{
FrameBufferD3D12& frameBuffer = m_frameBuffers[m_windows[ii].idx];
- hr = frameBuffer.present(syncInterval, flags);
+ hr = frameBuffer.present(syncInterval, presentFlags);
}
if (SUCCEEDED(hr)
&& NULL != m_swapChain)
{
- hr = m_swapChain->Present(syncInterval, flags);
+ hr = m_swapChain->Present(syncInterval, presentFlags);
}
int64_t now = bx::getHPCounter();
@@ -3173,14 +3182,6 @@ namespace bgfx { namespace d3d12
data = (const char*)m_uniforms[handle.idx];
}
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
- case UniformType::_uniform: \
- case UniformType::_uniform|kUniformFragmentBit: \
- { \
- setShaderUniform(uint8_t(type), loc, data, num); \
- } \
- break;
-
switch ( (uint32_t)type)
{
case UniformType::Mat3:
@@ -3207,9 +3208,16 @@ namespace bgfx { namespace d3d12
}
break;
- CASE_IMPLEMENT_UNIFORM(Sampler, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, F, float);
- CASE_IMPLEMENT_UNIFORM(Mat4, F, float);
+ case UniformType::Sampler:
+ case UniformType::Sampler | kUniformFragmentBit:
+ case UniformType::Vec4:
+ case UniformType::Vec4 | kUniformFragmentBit:
+ case UniformType::Mat4:
+ case UniformType::Mat4 | kUniformFragmentBit:
+ {
+ setShaderUniform(uint8_t(type), loc, data, num);
+ }
+ break;
case UniformType::End:
break;
@@ -3218,7 +3226,6 @@ namespace bgfx { namespace d3d12
BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
-#undef CASE_IMPLEMENT_UNIFORM
}
}
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index 255b17a0e24..c8088abe1c4 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -256,7 +256,7 @@ namespace bgfx { namespace gl
{ GL_RG16, GL_ZERO, GL_RG, GL_RG, GL_UNSIGNED_SHORT, false }, // RG16
{ GL_RG16I, GL_ZERO, RG_INTEGER, GL_RG_INTEGER, GL_SHORT, false }, // RG16I
{ GL_RG16UI, GL_ZERO, RG_INTEGER, GL_RG_INTEGER, GL_UNSIGNED_SHORT, false }, // RG16U
- { GL_RG16F, GL_ZERO, GL_RG, GL_RG, GL_FLOAT, false }, // RG16F
+ { GL_RG16F, GL_ZERO, GL_RG, GL_RG, GL_HALF_FLOAT, false }, // RG16F
{ GL_RG16_SNORM, GL_ZERO, GL_RG, GL_RG, GL_SHORT, false }, // RG16S
{ GL_RG32I, GL_ZERO, RG_INTEGER, GL_RG_INTEGER, GL_INT, false }, // RG32I
{ GL_RG32UI, GL_ZERO, RG_INTEGER, GL_RG_INTEGER, GL_UNSIGNED_INT, false }, // RG32U
@@ -4181,22 +4181,6 @@ namespace bgfx { namespace gl
uint32_t loc = _uniformBuffer.read();
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
- case UniformType::_uniform: \
- { \
- _type* value = (_type*)data; \
- setUniform##_glsuffix(loc, num, value); \
- } \
- break;
-
-#define CASE_IMPLEMENT_UNIFORM_T(_uniform, _glsuffix, _dxsuffix, _type) \
- case UniformType::_uniform: \
- { \
- _type* value = (_type*)data; \
- setUniform##_glsuffix(loc, num, GL_FALSE, value); \
- } \
- break;
-
switch (type)
{
#if BX_PLATFORM_EMSCRIPTEN
@@ -4204,19 +4188,42 @@ namespace bgfx { namespace gl
// since they need to marshal an array over from Wasm to JS, so optimize the case when there is exactly one
// uniform to upload.
case UniformType::Sampler:
- if (num > 1) setUniform1iv(loc, num, (int*)data);
- else setUniform1i(loc, *(int*)data);
+ if (num > 1)
+ {
+ setUniform1iv(loc, num, (int32_t*)data);
+ }
+ else
+ {
+ setUniform1i(loc, *(int32_t*)data);
+ }
break;
case UniformType::Vec4:
- if (num > 1) setUniform4fv(loc, num, (float*)data);
- else setUniform4f(loc, ( (float*)data)[0], ( (float*)data)[1], ( (float*)data)[2], ( (float*)data)[3]);
+ if (num > 1)
+ {
+ setUniform4fv(loc, num, (float*)data);
+ }
+ else
+ {
+ float* vec4 = (float*)data;
+ setUniform4f(loc, vec4[0], vec4[1], vec4[2], vec4[3]);
+ }
break;
#else
- CASE_IMPLEMENT_UNIFORM(Sampler, 1iv, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, 4fv, F, float);
+ case UniformType::Sampler:
+ setUniform1iv(loc, num, (int32_t*)data);
+ break;
+
+ case UniformType::Vec4:
+ setUniform4fv(loc, num, (float*)data);
+ break;
#endif
- CASE_IMPLEMENT_UNIFORM_T(Mat3, Matrix3fv, F, float);
- CASE_IMPLEMENT_UNIFORM_T(Mat4, Matrix4fv, F, float);
+ case UniformType::Mat3:
+ setUniformMatrix3fv(loc, num, GL_FALSE, (float*)data);
+ break;
+
+ case UniformType::Mat4:
+ setUniformMatrix4fv(loc, num, GL_FALSE, (float*)data);
+ break;
case UniformType::End:
break;
@@ -4225,10 +4232,6 @@ namespace bgfx { namespace gl
BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
-
-#undef CASE_IMPLEMENT_UNIFORM
-#undef CASE_IMPLEMENT_UNIFORM_T
-
}
}
diff --git a/3rdparty/bgfx/src/renderer_gnm.cpp b/3rdparty/bgfx/src/renderer_gnm.cpp
index 1592878b658..333bbb4649e 100644
--- a/3rdparty/bgfx/src/renderer_gnm.cpp
+++ b/3rdparty/bgfx/src/renderer_gnm.cpp
@@ -8,12 +8,12 @@
namespace bgfx
{
-#define BGFX_DECLARE_EMBEDDED_SHADER(_name) \
- extern const uint8_t* BX_CONCATENATE(_name, _pssl); \
- extern const uint32_t BX_CONCATENATE(_name, _pssl_size); \
- static const uint8_t BX_CONCATENATE(_name, _int_pssl)[] = { 0 }; \
- const uint8_t* BX_CONCATENATE(_name, _pssl) = &BX_CONCATENATE(_name, _int_pssl)[0]; \
- const uint32_t BX_CONCATENATE(_name, _pssl_size) = 1
+#define BGFX_DECLARE_EMBEDDED_SHADER(_name) \
+ extern const uint8_t* BX_CONCATENATE(_name, _pssl); \
+ extern const uint32_t BX_CONCATENATE(_name, _pssl_size); \
+ static const uint8_t BX_CONCATENATE(_name, _int_pssl)[] = { 0 }; \
+ const uint8_t* BX_CONCATENATE(_name, _pssl) = &BX_CONCATENATE(_name, _int_pssl)[0]; \
+ const uint32_t BX_CONCATENATE(_name, _pssl_size) = 1
BGFX_DECLARE_EMBEDDED_SHADER(vs_debugfont);
BGFX_DECLARE_EMBEDDED_SHADER(fs_debugfont);
@@ -42,4 +42,5 @@ namespace bgfx { namespace gnm
void rendererDestroy()
{
}
+
} /* namespace gnm */ } // namespace bgfx
diff --git a/3rdparty/bgfx/src/renderer_mtl.mm b/3rdparty/bgfx/src/renderer_mtl.mm
index 690e43fd349..74af2e5106a 100644
--- a/3rdparty/bgfx/src/renderer_mtl.mm
+++ b/3rdparty/bgfx/src/renderer_mtl.mm
@@ -1451,14 +1451,6 @@ namespace bgfx { namespace mtl
data = (const char*)m_uniforms[handle.idx];
}
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
- case UniformType::_uniform: \
- case UniformType::_uniform|kUniformFragmentBit: \
- { \
- setShaderUniform(uint8_t(type), loc, data, num); \
- } \
- break;
-
switch ( (uint32_t)type)
{
case UniformType::Mat3:
@@ -1485,9 +1477,16 @@ namespace bgfx { namespace mtl
}
break;
- CASE_IMPLEMENT_UNIFORM(Sampler, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, F, float);
- CASE_IMPLEMENT_UNIFORM(Mat4, F, float);
+ case UniformType::Sampler:
+ case UniformType::Sampler | kUniformFragmentBit:
+ case UniformType::Vec4:
+ case UniformType::Vec4 | kUniformFragmentBit:
+ case UniformType::Mat4:
+ case UniformType::Mat4 | kUniformFragmentBit:
+ {
+ setShaderUniform(uint8_t(type), loc, data, num);
+ }
+ break;
case UniformType::End:
break;
@@ -1496,9 +1495,6 @@ namespace bgfx { namespace mtl
BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
-
-#undef CASE_IMPLEMENT_UNIFORM
-
}
}
@@ -4004,6 +4000,18 @@ namespace bgfx { namespace mtl
if (desc.texture != NULL)
{
desc.loadAction = MTLLoadActionLoad;
+
+ if (NULL != m_capture
+ && !isValid(fbh)
+ && m_hasStoreActionStoreAndMultisampleResolve)
+ {
+ desc.storeAction = desc.texture.sampleCount > 1 ? MTLStoreActionStoreAndMultisampleResolve : MTLStoreActionStore;
+
+ }
+ else
+ {
+ desc.storeAction = desc.texture.sampleCount > 1 ? MTLStoreActionMultisampleResolve : MTLStoreActionStore;
+ }
}
}
diff --git a/3rdparty/bgfx/src/renderer_nvn.cpp b/3rdparty/bgfx/src/renderer_nvn.cpp
index a03f59bf008..799264a2c35 100644
--- a/3rdparty/bgfx/src/renderer_nvn.cpp
+++ b/3rdparty/bgfx/src/renderer_nvn.cpp
@@ -8,10 +8,10 @@
namespace bgfx
{
-#define BGFX_DECLARE_EMBEDDED_SHADER(_name) \
- extern const uint8_t* BX_CONCATENATE(_name, _nvn); \
- extern const uint32_t BX_CONCATENATE(_name, _nvn_size); \
- static const uint8_t BX_CONCATENATE(_name, _int_nvn)[] = { 0 }; \
+#define BGFX_DECLARE_EMBEDDED_SHADER(_name) \
+ extern const uint8_t* BX_CONCATENATE(_name, _nvn); \
+ extern const uint32_t BX_CONCATENATE(_name, _nvn_size); \
+ static const uint8_t BX_CONCATENATE(_name, _int_nvn)[] = { 0 }; \
const uint8_t* BX_CONCATENATE(_name, _nvn) = &BX_CONCATENATE(_name, _int_nvn)[0]; \
const uint32_t BX_CONCATENATE(_name, _nvn_size) = 1
@@ -42,4 +42,5 @@ namespace bgfx { namespace nvn
void rendererDestroy()
{
}
+
} /* namespace nvn */ } // namespace bgfx
diff --git a/3rdparty/bgfx/src/renderer_vk.cpp b/3rdparty/bgfx/src/renderer_vk.cpp
index d4268ef776b..6bff243f8b5 100644
--- a/3rdparty/bgfx/src/renderer_vk.cpp
+++ b/3rdparty/bgfx/src/renderer_vk.cpp
@@ -2828,8 +2828,8 @@ VK_IMPORT_DEVICE
newFrameBuffer.acquire(m_commandBuffer);
int64_t now = bx::getHPCounter();
-
- if (NULL == newFrameBuffer.m_nwh)
+
+ if (NULL != newFrameBuffer.m_nwh)
{
m_presentElapsed += now - start;
}
@@ -4057,14 +4057,6 @@ VK_IMPORT_DEVICE
data = (const char*)m_uniforms[handle.idx];
}
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
- case UniformType::_uniform: \
- case UniformType::_uniform|kUniformFragmentBit: \
- { \
- setShaderUniform(uint8_t(type), loc, data, num); \
- } \
- break;
-
switch ( (uint32_t)type)
{
case UniformType::Mat3:
@@ -4095,9 +4087,15 @@ VK_IMPORT_DEVICE
case UniformType::Sampler|kUniformFragmentBit:
// do nothing, but VkDescriptorSetImageInfo would be set before drawing
break;
-// CASE_IMPLEMENT_UNIFORM(Sampler, I, int);
- CASE_IMPLEMENT_UNIFORM(Vec4, F, float);
- CASE_IMPLEMENT_UNIFORM(Mat4, F, float);
+
+ case UniformType::Vec4:
+ case UniformType::Vec4 | kUniformFragmentBit:
+ case UniformType::Mat4:
+ case UniformType::Mat4 | kUniformFragmentBit:
+ {
+ setShaderUniform(uint8_t(type), loc, data, num);
+ }
+ break;
case UniformType::End:
break;
@@ -4106,7 +4104,6 @@ VK_IMPORT_DEVICE
BX_TRACE("%4d: INVALID 0x%08x, t %d, l %d, n %d, c %d", _uniformBuffer.getPos(), opcode, type, loc, num, copy);
break;
}
-#undef CASE_IMPLEMENT_UNIFORM
}
}
@@ -6121,11 +6118,25 @@ VK_DESTROY
region.bufferImageHeight = 0;
region.imageSubresource.aspectMask = m_aspectMask;
region.imageSubresource.mipLevel = _mip;
- region.imageSubresource.baseArrayLayer = _side;
+ region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = 1;
- region.imageOffset = { _rect.m_x, _rect.m_y, _z };
+ region.imageOffset = { _rect.m_x, _rect.m_y, 0 };
region.imageExtent = { _rect.m_width, _rect.m_height, _depth };
+ if (VK_IMAGE_VIEW_TYPE_3D == m_type)
+ {
+ region.imageOffset.z = _z;
+ }
+ else if (VK_IMAGE_VIEW_TYPE_CUBE == m_type
+ || VK_IMAGE_VIEW_TYPE_CUBE_ARRAY == m_type)
+ {
+ region.imageSubresource.baseArrayLayer = _z * 6 + _side;
+ }
+ else
+ {
+ region.imageSubresource.baseArrayLayer = _z;
+ }
+
copyBufferToTexture(_commandBuffer, stagingBuffer, 1, &region);
s_renderVK->release(stagingBuffer);
@@ -6142,6 +6153,7 @@ VK_DESTROY
const bool needResolve = VK_NULL_HANDLE != m_singleMsaaImage;
const bool needMipGen = true
+ && !needResolve
&& 0 != (m_flags & BGFX_TEXTURE_RT_MASK)
&& 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY)
&& (_mip + 1) < m_numMips
@@ -6185,24 +6197,13 @@ VK_DESTROY
);
}
- if (needResolve && needMipGen)
- {
- setMemoryBarrier(
- _commandBuffer
- , VK_PIPELINE_STAGE_TRANSFER_BIT
- , VK_PIPELINE_STAGE_TRANSFER_BIT
- );
- }
-
if (needMipGen)
{
- setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, needResolve);
+ setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
int32_t mipWidth = bx::max<int32_t>(int32_t(m_width) >> _mip, 1);
int32_t mipHeight = bx::max<int32_t>(int32_t(m_height) >> _mip, 1);
- const VkImage image = needResolve ? m_singleMsaaImage : m_textureImage;
-
const VkFilter filter = bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
? VK_FILTER_NEAREST
: VK_FILTER_LINEAR
@@ -6235,7 +6236,7 @@ VK_DESTROY
vk::setImageMemoryBarrier(
_commandBuffer
- , image
+ , m_textureImage
, m_aspectMask
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
@@ -6247,9 +6248,9 @@ VK_DESTROY
vkCmdBlitImage(
_commandBuffer
- , image
+ , m_textureImage
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
- , image
+ , m_textureImage
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
, 1
, &blit
@@ -6259,7 +6260,7 @@ VK_DESTROY
vk::setImageMemoryBarrier(
_commandBuffer
- , image
+ , m_textureImage
, m_aspectMask
, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
@@ -6794,16 +6795,16 @@ VK_DESTROY
const uint32_t minSwapBufferCount = bx::max<uint32_t>(surfaceCapabilities.minImageCount, 2);
const uint32_t maxSwapBufferCount = surfaceCapabilities.maxImageCount == 0
- ? BGFX_CONFIG_MAX_BACK_BUFFERS
- : bx::min<uint32_t>(surfaceCapabilities.maxImageCount, BGFX_CONFIG_MAX_BACK_BUFFERS)
+ ? kMaxBackBuffers
+ : bx::min<uint32_t>(surfaceCapabilities.maxImageCount, kMaxBackBuffers)
;
if (minSwapBufferCount > maxSwapBufferCount)
{
- BX_TRACE("Create swapchain error: Incompatible swapchain image count (min: %d, max: %d, BGFX_CONFIG_MAX_BACK_BUFFERS: %d)."
+ BX_TRACE("Create swapchain error: Incompatible swapchain image count (min: %d, max: %d, MaxBackBuffers: %d)."
, minSwapBufferCount
, maxSwapBufferCount
- , BGFX_CONFIG_MAX_BACK_BUFFERS
+ , kMaxBackBuffers
);
return VK_ERROR_INITIALIZATION_FAILED;
}
@@ -7309,6 +7310,7 @@ VK_DESTROY
BX_FALLTHROUGH;
case VK_ERROR_OUT_OF_DATE_KHR:
+ case VK_SUBOPTIMAL_KHR:
m_needToRefreshSwapchain = true;
return false;
diff --git a/3rdparty/bgfx/src/renderer_vk.h b/3rdparty/bgfx/src/renderer_vk.h
index 54c08814458..3e14799035d 100644
--- a/3rdparty/bgfx/src/renderer_vk.h
+++ b/3rdparty/bgfx/src/renderer_vk.h
@@ -660,6 +660,8 @@ VK_DESTROY_FUNC(DescriptorSet);
static VkImageAspectFlags getAspectMask(VkFormat _format);
};
+ constexpr uint32_t kMaxBackBuffers = bx::max(BGFX_CONFIG_MAX_BACK_BUFFERS, 10);
+
struct SwapChainVK
{
SwapChainVK()
@@ -672,7 +674,7 @@ VK_DESTROY_FUNC(DescriptorSet);
}
VkResult create(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution, TextureFormat::Enum _depthFormat = TextureFormat::Count);
-
+
void destroy();
void update(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution);
@@ -707,24 +709,24 @@ VK_DESTROY_FUNC(DescriptorSet);
VkSurfaceKHR m_surface;
VkSwapchainKHR m_swapchain;
uint32_t m_numSwapchainImages;
- VkImageLayout m_backBufferColorImageLayout[BGFX_CONFIG_MAX_BACK_BUFFERS];
- VkImage m_backBufferColorImage[BGFX_CONFIG_MAX_BACK_BUFFERS];
- VkImageView m_backBufferColorImageView[BGFX_CONFIG_MAX_BACK_BUFFERS];
- VkFramebuffer m_backBufferFrameBuffer[BGFX_CONFIG_MAX_BACK_BUFFERS];
- VkFence m_backBufferFence[BGFX_CONFIG_MAX_BACK_BUFFERS];
+ VkImageLayout m_backBufferColorImageLayout[kMaxBackBuffers];
+ VkImage m_backBufferColorImage[kMaxBackBuffers];
+ VkImageView m_backBufferColorImageView[kMaxBackBuffers];
+ VkFramebuffer m_backBufferFrameBuffer[kMaxBackBuffers];
+ VkFence m_backBufferFence[kMaxBackBuffers];
uint32_t m_backBufferColorIdx;
- VkSemaphore m_presentDoneSemaphore[BGFX_CONFIG_MAX_BACK_BUFFERS];
- VkSemaphore m_renderDoneSemaphore[BGFX_CONFIG_MAX_BACK_BUFFERS];
+ VkSemaphore m_presentDoneSemaphore[kMaxBackBuffers];
+ VkSemaphore m_renderDoneSemaphore[kMaxBackBuffers];
uint32_t m_currentSemaphore;
VkSemaphore m_lastImageRenderedSemaphore;
VkSemaphore m_lastImageAcquiredSemaphore;
-
+
bool m_needPresent;
bool m_needToRefreshSwapchain;
bool m_needToRecreateSurface;
-
+
TextureVK m_backBufferDepthStencil;
VkImageView m_backBufferDepthStencilImageView;
diff --git a/3rdparty/bgfx/src/vertexlayout.cpp b/3rdparty/bgfx/src/vertexlayout.cpp
index 2235bc36c9f..35bec28c00e 100644
--- a/3rdparty/bgfx/src/vertexlayout.cpp
+++ b/3rdparty/bgfx/src/vertexlayout.cpp
@@ -44,6 +44,7 @@ namespace bgfx
static const uint8_t (*s_attribTypeSize[])[AttribType::Count][4] =
{
&s_attribTypeSizeD3D9, // Noop
+ &s_attribTypeSizeD3D1x, // Agc
&s_attribTypeSizeD3D9, // Direct3D9
&s_attribTypeSizeD3D1x, // Direct3D11
&s_attribTypeSizeD3D1x, // Direct3D12
diff --git a/3rdparty/bgfx/tools/geometryc/geometryc.cpp b/3rdparty/bgfx/tools/geometryc/geometryc.cpp
index d2aff270f58..d604fd38269 100644
--- a/3rdparty/bgfx/tools/geometryc/geometryc.cpp
+++ b/3rdparty/bgfx/tools/geometryc/geometryc.cpp
@@ -589,7 +589,7 @@ void parseObj(char* _data, uint32_t _size, Mesh* _mesh, bool _hasBc)
if (0 == bx::strCmp(argv[0], "vn") )
{
- bx::Vec3 normal;
+ bx::Vec3 normal(bx::init::None);
bx::fromString(&normal.x, argv[1]);
bx::fromString(&normal.y, argv[2]);
bx::fromString(&normal.z, argv[3]);
@@ -607,7 +607,7 @@ void parseObj(char* _data, uint32_t _size, Mesh* _mesh, bool _hasBc)
}
else if (0 == bx::strCmp(argv[0], "vt") )
{
- bx::Vec3 texcoord;
+ bx::Vec3 texcoord(bx::init::None);
texcoord.y = 0.0f;
texcoord.z = 0.0f;
@@ -645,15 +645,10 @@ void parseObj(char* _data, uint32_t _size, Mesh* _mesh, bool _hasBc)
pw = 1.0f;
}
- float invW = 1.0f/pw;
- px *= invW;
- py *= invW;
- pz *= invW;
+ bx::Vec3 pos(px, py, pz);
- bx::Vec3 pos;
- pos.x = px;
- pos.y = py;
- pos.z = pz;
+ const float invW = bx::rcp(pw);
+ pos = bx::mul(pos, invW);
_mesh->m_positions.push_back(pos);
}
@@ -753,8 +748,9 @@ void processGltfNode(cgltf_node* _node, Mesh* _mesh, Group* _group, bool _hasBc)
{
_mesh->m_positions.reserve(_mesh->m_positions.size() + accessorCount);
- bx::Vec3 pos;
- for (cgltf_size v=0;v<accessorCount;++v)
+ bx::Vec3 pos(bx::init::None);
+
+ for (cgltf_size v = 0; v < accessorCount; ++v)
{
gltfReadFloat(accessorData, numComponents, v, &pos.x, 3);
pos = mul(pos, nodeToWorld);
@@ -766,8 +762,9 @@ void processGltfNode(cgltf_node* _node, Mesh* _mesh, Group* _group, bool _hasBc)
_mesh->m_normals.reserve(_mesh->m_normals.size() + accessorCount);
hasNormal = true;
- bx::Vec3 normal;
- for (cgltf_size v=0;v<accessorCount;++v)
+ bx::Vec3 normal(bx::init::None);
+
+ for (cgltf_size v = 0; v < accessorCount; ++v)
{
gltfReadFloat(accessorData, numComponents, v, &normal.x, 3);
normal = mul(normal, nodeToWorldNormal);
@@ -779,8 +776,9 @@ void processGltfNode(cgltf_node* _node, Mesh* _mesh, Group* _group, bool _hasBc)
_mesh->m_texcoords.reserve(_mesh->m_texcoords.size() + accessorCount);
hasTexcoord = true;
- bx::Vec3 texcoord;
- for (cgltf_size v=0;v<accessorCount;++v)
+ bx::Vec3 texcoord(bx::init::None);
+
+ for (cgltf_size v = 0; v < accessorCount; ++v)
{
gltfReadFloat(accessorData, numComponents, v, &texcoord.x, 3);
_mesh->m_texcoords.push_back(texcoord);
diff --git a/3rdparty/bgfx/tools/geometryv/geometryv.cpp b/3rdparty/bgfx/tools/geometryv/geometryv.cpp
index 52befb53db6..adf15b2f358 100644
--- a/3rdparty/bgfx/tools/geometryv/geometryv.cpp
+++ b/3rdparty/bgfx/tools/geometryv/geometryv.cpp
@@ -169,7 +169,7 @@ struct Camera
{
Camera()
{
- init(bx::Vec3(0.0f,0.0f,0.0f), 2.0f, 0.01f, 100.0f);
+ init(bx::init::Zero, 2.0f, 0.01f, 100.0f);
}
void init(const bx::Vec3& _center, float _distance, float _near, float _far)
@@ -265,8 +265,8 @@ struct Camera
struct Interp3f
{
- bx::Vec3 curr;
- bx::Vec3 dest;
+ bx::Vec3 curr = bx::init::None;
+ bx::Vec3 dest = bx::init::None;
};
Interp3f m_target;
diff --git a/3rdparty/bgfx/tools/shaderc/shaderc.cpp b/3rdparty/bgfx/tools/shaderc/shaderc.cpp
index eb83edda25e..7932dec0204 100644
--- a/3rdparty/bgfx/tools/shaderc/shaderc.cpp
+++ b/3rdparty/bgfx/tools/shaderc/shaderc.cpp
@@ -2304,7 +2304,7 @@ namespace bgfx
);
}
- if (need130)
+ if (need130 || (glsl_profile >= 130))
{
bx::stringPrintf(code
, "#define bgfxShadow2D(_sampler, _coord) vec4_splat(texture(_sampler, _coord))\n"
@@ -2370,6 +2370,13 @@ namespace bgfx
"#define shadow2DProj shadow2DProjEXT\n"
);
}
+ else
+ {
+ bx::stringPrintf(code
+ , "#define shadow2D(_sampler, _coord) texture(_sampler, _coord)\n"
+ "#define shadow2DProj(_sampler, _coord) textureProj(_sampler, _coord)\n"
+ );
+ }
if (usesGpuShader5)
{
diff --git a/3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp b/3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp
index 0c40b1fb822..1069e1a3cd9 100644
--- a/3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp
+++ b/3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp
@@ -636,6 +636,11 @@ namespace bgfx { namespace spirv
Uniform un;
un.name = program->getUniformName(ii);
+ if (bx::hasSuffix(un.name.c_str(), ".@data") )
+ {
+ continue;
+ }
+
un.num = 0;
const uint32_t offset = program->getUniformBufferOffset(ii);
un.regIndex = uint16_t(offset);
@@ -800,6 +805,7 @@ namespace bgfx { namespace spirv
for (auto& resource : resourcesrefl.storage_buffers)
{
std::string name = refl.get_name(resource.id);
+
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id);
diff --git a/3rdparty/bimg/.travis.yml b/3rdparty/bimg/.travis.yml
deleted file mode 100644
index 566b2eabf0e..00000000000
--- a/3rdparty/bimg/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-language: cpp
-matrix:
- include:
- - compiler: gcc
- os: linux
- - compiler: clang
- os: osx
-
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - gcc-8
- - g++-8
- - clang
-
-before_script:
- git clone https://github.com/bkaradzic/bx ../bx
-
-script:
- - if [ "$TRAVIS_OS_NAME" == "linux" ]; then make build CXX="g++-8" CC="gcc-8"; fi
- - if [ "$TRAVIS_OS_NAME" == "osx" ]; then make build; fi
-
-branches:
- only:
- - master
-
-notifications:
- email: false
-
-osx_image: xcode11
diff --git a/3rdparty/bimg/README.md b/3rdparty/bimg/README.md
index d0eefa39729..ea37931f46e 100644
--- a/3rdparty/bimg/README.md
+++ b/3rdparty/bimg/README.md
@@ -3,7 +3,6 @@ bimg
Image library.
-[![Build Status](https://travis-ci.com/bkaradzic/bx.svg?branch=master)](https://travis-ci.com/bkaradzic/bimg)
[![Build status](https://ci.appveyor.com/api/projects/status/edras3mltmoy31g5?svg=true)](https://ci.appveyor.com/project/bkaradzic/bimg)
[![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://bkaradzic.github.io/bgfx/license.html)
[![Join the chat at https://discord.gg/9eMbv7J](https://img.shields.io/discord/712512073522872352?color=%237289DA&label=bimg&logo=discord&logoColor=white)](https://discord.gg/9eMbv7J)
diff --git a/3rdparty/bimg/src/image_cubemap_filter.cpp b/3rdparty/bimg/src/image_cubemap_filter.cpp
index 94d4cd5f72c..fcc36fc8f6e 100644
--- a/3rdparty/bimg/src/image_cubemap_filter.cpp
+++ b/3rdparty/bimg/src/image_cubemap_filter.cpp
@@ -849,8 +849,8 @@ namespace bimg
const float kGoldenSection = 0.61803398875f;
float offset = kGoldenSection;
- bx::Vec3 tangentX;
- bx::Vec3 tangentY;
+ bx::Vec3 tangentX(bx::init::None);
+ bx::Vec3 tangentY(bx::init::None);
bx::calcTangentFrame(tangentX, tangentY, _dir);
for (uint32_t ii = 0; ii < kNumSamples; ++ii)
diff --git a/3rdparty/bx/.travis.yml b/3rdparty/bx/.travis.yml
deleted file mode 100644
index 82e0ac2e024..00000000000
--- a/3rdparty/bx/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: cpp
-matrix:
- include:
- - compiler: gcc
- os: linux
- - compiler: clang
- os: osx
-
-addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- packages:
- - gcc-8
- - g++-8
- - clang
-
-script:
- - if [ "$TRAVIS_OS_NAME" == "linux" ]; then make test CXX="g++-8" CC="gcc-8"; fi
- - if [ "$TRAVIS_OS_NAME" == "osx" ]; then make test; fi
-
-branches:
- only:
- - master
-
-notifications:
- email: false
-
-osx_image: xcode11
diff --git a/3rdparty/bx/README.md b/3rdparty/bx/README.md
index 3a6547daf5c..16d74f16ac5 100644
--- a/3rdparty/bx/README.md
+++ b/3rdparty/bx/README.md
@@ -3,7 +3,6 @@ bx
Base library.
-[![Build Status](https://travis-ci.com/bkaradzic/bx.svg?branch=master)](https://travis-ci.com/bkaradzic/bx)
[![Build status](https://ci.appveyor.com/api/projects/status/edras3mltmoy31g5?svg=true)](https://ci.appveyor.com/project/bkaradzic/bx)
[![License](https://img.shields.io/badge/license-BSD--2%20clause-blue.svg)](https://bkaradzic.github.io/bgfx/license.html)
[![Join the chat at https://discord.gg/9eMbv7J](https://img.shields.io/discord/712512073522872352?color=%237289DA&label=bx&logo=discord&logoColor=white)](https://discord.gg/9eMbv7J)
diff --git a/3rdparty/bx/include/bx/inline/math.inl b/3rdparty/bx/include/bx/inline/math.inl
index 1da6b2d2c32..6699a73bf55 100644
--- a/3rdparty/bx/include/bx/inline/math.inl
+++ b/3rdparty/bx/include/bx/inline/math.inl
@@ -286,9 +286,24 @@ namespace bx
return _c - _a * _b;
}
+ inline BX_CONSTEXPR_FUNC float add(float _a, float _b)
+ {
+ return _a + _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC float sub(float _a, float _b)
+ {
+ return _a - _b;
+ }
+
+ inline BX_CONSTEXPR_FUNC float mul(float _a, float _b)
+ {
+ return _a * _b;
+ }
+
inline BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c)
{
- return _a * _b + _c;
+ return add(mul(_a, _b), _c);
}
inline BX_CONSTEXPR_FUNC float rcp(float _a)
@@ -383,7 +398,7 @@ namespace bx
template<typename Ty>
inline Ty load(const void* _ptr)
{
- Ty result;
+ Ty result(init::None);
memCopy(&result, _ptr, sizeof(Ty) );
return result;
}
@@ -394,7 +409,21 @@ namespace bx
memCopy(_ptr, &_a, sizeof(Ty) );
}
- inline Vec3::Vec3()
+ inline Vec3::Vec3(init::NoneType)
+ {
+ }
+
+ constexpr Vec3::Vec3(init::ZeroType)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ {
+ }
+
+ constexpr Vec3::Vec3(init::IdentityType)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
{
}
@@ -412,6 +441,57 @@ namespace bx
{
}
+ inline Plane::Plane(init::NoneType)
+ : normal(init::None)
+ {
+ }
+
+ constexpr Plane::Plane(init::ZeroType)
+ : normal(init::Zero)
+ , dist(0.0f)
+ {
+ }
+
+ constexpr Plane::Plane(init::IdentityType)
+ : normal(0.0f, 1.0f, 0.0f)
+ , dist(0.0f)
+ {
+ }
+
+ constexpr Plane::Plane(Vec3 _normal, float _dist)
+ : normal(_normal)
+ , dist(_dist)
+ {
+ }
+
+ inline Quaternion::Quaternion(init::NoneType)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(init::ZeroType)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ , w(0.0f)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(init::IdentityType)
+ : x(0.0f)
+ , y(0.0f)
+ , z(0.0f)
+ , w(1.0f)
+ {
+ }
+
+ constexpr Quaternion::Quaternion(float _x, float _y, float _z, float _w)
+ : x(_x)
+ , y(_y)
+ , z(_z)
+ , w(_w)
+ {
+ }
+
inline BX_CONSTEXPR_FUNC Vec3 round(const Vec3 _a)
{
return
@@ -650,7 +730,7 @@ namespace bx
inline BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v)
{
- Vec3 result;
+ Vec3 result(init::None);
const float phi = _u * kPi2;
const float theta = _v * kPi;
@@ -705,6 +785,39 @@ namespace bx
};
}
+ inline BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b)
+ {
+ return
+ {
+ _a.x + _b.x,
+ _a.y + _b.y,
+ _a.z + _b.z,
+ _a.w + _b.w,
+ };
+ }
+
+ inline BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b)
+ {
+ return
+ {
+ _a.x - _b.x,
+ _a.y - _b.y,
+ _a.z - _b.z,
+ _a.w - _b.w,
+ };
+ }
+
+ inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b)
+ {
+ return
+ {
+ _a.x * _b,
+ _a.y * _b,
+ _a.z * _b,
+ _a.w * _b,
+ };
+ }
+
inline BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b)
{
const float ax = _a.x;
@@ -751,15 +864,9 @@ namespace bx
const float norm = dot(_a, _a);
if (0.0f < norm)
{
- const float invNorm = 1.0f / sqrt(norm);
-
- return
- {
- _a.x * invNorm,
- _a.y * invNorm,
- _a.z * invNorm,
- _a.w * invNorm,
- };
+ const float invNorm = rsqrt(norm);
+
+ return mul(_a, invNorm);
}
return
@@ -771,6 +878,19 @@ namespace bx
};
}
+ inline BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t)
+ {
+ const float sa = 1.0f - _t;
+ const float adotb = dot(_a, _b);
+ const float sb = sign(adotb) * _t;
+
+ const Quaternion aa = mul(_a, sa);
+ const Quaternion bb = mul(_b, sb);
+ const Quaternion qq = add(aa, bb);
+
+ return normalize(qq);
+ }
+
inline BX_CONST_FUNC Vec3 toEuler(const Quaternion _a)
{
const float xx = _a.x;
@@ -789,6 +909,57 @@ namespace bx
};
}
+ inline BX_CONST_FUNC Vec3 toXAxis(const Quaternion _a)
+ {
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float ysq = square(yy);
+ const float zsq = square(zz);
+
+ return
+ {
+ 1.0f - 2.0f * ysq - 2.0f * zsq,
+ 2.0f * xx * yy + 2.0f * zz * ww,
+ 2.0f * xx * zz - 2.0f * yy * ww,
+ };
+ }
+
+ inline BX_CONST_FUNC Vec3 toYAxis(const Quaternion _a)
+ {
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float xsq = square(xx);
+ const float zsq = square(zz);
+
+ return
+ {
+ 2.0f * xx * yy - 2.0f * zz * ww,
+ 1.0f - 2.0f * xsq - 2.0f * zsq,
+ 2.0f * yy * zz + 2.0f * xx * ww,
+ };
+ }
+
+ inline BX_CONST_FUNC Vec3 toZAxis(const Quaternion _a)
+ {
+ const float xx = _a.x;
+ const float yy = _a.y;
+ const float zz = _a.z;
+ const float ww = _a.w;
+ const float xsq = square(xx);
+ const float ysq = square(yy);
+
+ return
+ {
+ 2.0f * xx * zz + 2.0f * yy * ww,
+ 2.0f * yy * zz - 2.0f * xx * ww,
+ 1.0f - 2.0f * xsq - 2.0f * ysq,
+ };
+ }
+
inline BX_CONST_FUNC Quaternion rotateAxis(const Vec3 _axis, float _angle)
{
const float ha = _angle * 0.5f;
@@ -872,8 +1043,8 @@ namespace bx
inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos)
{
- Vec3 tangent;
- Vec3 bitangent;
+ Vec3 tangent(init::None);
+ Vec3 bitangent(init::None);
calcTangentFrame(tangent, bitangent, _normal);
store(&_result[ 0], mul(bitangent, _scale) );
@@ -891,8 +1062,8 @@ namespace bx
inline void mtxFromNormal(float* _result, const Vec3& _normal, float _scale, const Vec3& _pos, float _angle)
{
- Vec3 tangent;
- Vec3 bitangent;
+ Vec3 tangent(init::None);
+ Vec3 bitangent(init::None);
calcTangentFrame(tangent, bitangent, _normal, _angle);
store(&_result[0], mul(bitangent, _scale) );
@@ -969,7 +1140,7 @@ namespace bx
inline Vec3 mul(const Vec3& _vec, const float* _mat)
{
- Vec3 result;
+ Vec3 result(init::None);
result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8] + _mat[12];
result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9] + _mat[13];
result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10] + _mat[14];
@@ -978,7 +1149,7 @@ namespace bx
inline Vec3 mulXyz0(const Vec3& _vec, const float* _mat)
{
- Vec3 result;
+ Vec3 result(init::None);
result.x = _vec.x * _mat[0] + _vec.y * _mat[4] + _vec.z * _mat[ 8];
result.y = _vec.x * _mat[1] + _vec.y * _mat[5] + _vec.z * _mat[ 9];
result.z = _vec.x * _mat[2] + _vec.y * _mat[6] + _vec.z * _mat[10];
diff --git a/3rdparty/bx/include/bx/inline/string.inl b/3rdparty/bx/include/bx/inline/string.inl
index 1aa830f2f74..e049b0c343b 100644
--- a/3rdparty/bx/include/bx/inline/string.inl
+++ b/3rdparty/bx/include/bx/inline/string.inl
@@ -292,4 +292,20 @@ namespace bx
return m_line;
}
+ inline bool hasPrefix(const StringView& _str, const StringView& _prefix)
+ {
+ const int32_t len = _prefix.getLength();
+ return _str.getLength() >= len
+ && 0 == strCmp(_str, _prefix, len)
+ ;
+ }
+
+ inline bool hasSuffix(const StringView& _str, const StringView& _suffix)
+ {
+ const int32_t len = _suffix.getLength();
+ return _str.getLength() >= len
+ && 0 == strCmp(StringView(_str.getTerm() - len, _str.getTerm() ), _suffix, len)
+ ;
+ }
+
} // namespace bx
diff --git a/3rdparty/bx/include/bx/math.h b/3rdparty/bx/include/bx/math.h
index bd05e84d7ac..ee4aa292276 100644
--- a/3rdparty/bx/include/bx/math.h
+++ b/3rdparty/bx/include/bx/math.h
@@ -50,11 +50,38 @@ namespace bx
};
};
+ /// Structure initializer types.
+ namespace init
+ {
+ /// Fields are left uninitialized.
+ ///
+ struct NoneType {};
+ constexpr NoneType None;
+
+ /// Fields are initialized to zero.
+ ///
+ struct ZeroType {};
+ constexpr ZeroType Zero;
+
+ /// Fields are initialized to identity value.
+ ///
+ struct IdentityType {};
+ constexpr IdentityType Identity;
+ }
+
///
struct Vec3
{
+ Vec3() = delete;
+
+ ///
+ Vec3(init::NoneType);
+
///
- Vec3();
+ constexpr Vec3(init::ZeroType);
+
+ ///
+ constexpr Vec3(init::IdentityType);
///
explicit constexpr Vec3(float _v);
@@ -68,6 +95,20 @@ namespace bx
///
struct Plane
{
+ Plane() = delete;
+
+ ///
+ Plane(init::NoneType);
+
+ ///
+ constexpr Plane(init::ZeroType);
+
+ ///
+ constexpr Plane(init::IdentityType);
+
+ ///
+ constexpr Plane(Vec3 _normal, float _dist);
+
Vec3 normal;
float dist;
};
@@ -75,6 +116,20 @@ namespace bx
///
struct Quaternion
{
+ Quaternion() = delete;
+
+ ///
+ Quaternion(init::NoneType);
+
+ ///
+ constexpr Quaternion(init::ZeroType);
+
+ ///
+ constexpr Quaternion(init::IdentityType);
+
+ ///
+ constexpr Quaternion(float _x, float _y, float _z, float _w);
+
float x, y, z, w;
};
@@ -253,11 +308,24 @@ namespace bx
///
BX_CONSTEXPR_FUNC float nms(float _a, float _b, float _c);
- /// Returns result of multipla and add (_a * _b + _c).
+ /// Returns resul of addition (_a + _b).
+ ///
+ BX_CONSTEXPR_FUNC float add(float _a, float _b);
+
+ /// Returns resul of subtracion (_a - _b).
+ ///
+ BX_CONSTEXPR_FUNC float sub(float _a, float _b);
+
+ /// Returns result of multiply (_a * _b).
+ ///
+ BX_CONSTEXPR_FUNC float mul(float _a, float _b);
+
+ /// Returns result of multiply and add (_a * _b + _c).
///
BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c);
/// Returns reciprocal of _a.
+ ///
BX_CONSTEXPR_FUNC float rcp(float _a);
/// Returns the floating-point remainder of the division operation _a/_b.
@@ -376,6 +444,7 @@ namespace bx
BX_CONSTEXPR_FUNC Vec3 max(const Vec3 _a, const Vec3 _b);
/// Returns component wise reciprocal of _a.
+ ///
BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3 _a);
///
@@ -397,6 +466,15 @@ namespace bx
BX_CONSTEXPR_FUNC Vec3 mulXyz(const Quaternion _a, const Quaternion _b);
///
+ BX_CONSTEXPR_FUNC Quaternion add(const Quaternion _a, const Quaternion _b);
+
+ ///
+ BX_CONSTEXPR_FUNC Quaternion sub(const Quaternion _a, const Quaternion _b);
+
+ ///
+ BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, float _b);
+
+ ///
BX_CONSTEXPR_FUNC Quaternion mul(const Quaternion _a, const Quaternion _b);
///
@@ -409,9 +487,21 @@ namespace bx
BX_CONSTEXPR_FUNC Quaternion normalize(const Quaternion _a);
///
+ BX_CONSTEXPR_FUNC Quaternion lerp(const Quaternion _a, const Quaternion _b, float _t);
+
+ ///
BX_CONST_FUNC Vec3 toEuler(const Quaternion _a);
///
+ BX_CONST_FUNC Vec3 toXAxis(const Quaternion _a);
+
+ ///
+ BX_CONST_FUNC Vec3 toYAxis(const Quaternion _a);
+
+ ///
+ BX_CONST_FUNC Vec3 toZAxis(const Quaternion _a);
+
+ ///
BX_CONST_FUNC Quaternion rotateAxis(const Vec3 _axis, float _angle);
///
diff --git a/3rdparty/bx/include/bx/platform.h b/3rdparty/bx/include/bx/platform.h
index eea5fcb04e2..b255636e5ba 100644
--- a/3rdparty/bx/include/bx/platform.h
+++ b/3rdparty/bx/include/bx/platform.h
@@ -56,6 +56,7 @@
#define BX_PLATFORM_NX 0
#define BX_PLATFORM_OSX 0
#define BX_PLATFORM_PS4 0
+#define BX_PLATFORM_PS5 0
#define BX_PLATFORM_RPI 0
#define BX_PLATFORM_WINDOWS 0
#define BX_PLATFORM_WINRT 0
@@ -203,6 +204,9 @@
#elif defined(__ORBIS__)
# undef BX_PLATFORM_PS4
# define BX_PLATFORM_PS4 1
+#elif defined(__PROSPERO__)
+# undef BX_PLATFORM_PS5
+# define BX_PLATFORM_PS5 1
#elif defined(__FreeBSD__) \
|| defined(__FreeBSD_kernel__) \
|| defined(__NetBSD__) \
@@ -268,6 +272,7 @@
|| BX_PLATFORM_NX \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
|| BX_PLATFORM_RPI \
)
@@ -283,6 +288,7 @@
|| BX_PLATFORM_NX \
|| BX_PLATFORM_OSX \
|| BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
|| BX_PLATFORM_RPI \
|| BX_PLATFORM_WINDOWS \
|| BX_PLATFORM_WINRT \
@@ -293,6 +299,7 @@
#define BX_PLATFORM_OS_CONSOLE (0 \
|| BX_PLATFORM_NX \
|| BX_PLATFORM_PS4 \
+ || BX_PLATFORM_PS5 \
|| BX_PLATFORM_WINRT \
|| BX_PLATFORM_XBOXONE \
)
@@ -380,6 +387,8 @@
# define BX_PLATFORM_NAME "OSX"
#elif BX_PLATFORM_PS4
# define BX_PLATFORM_NAME "PlayStation 4"
+#elif BX_PLATFORM_PS5
+# define BX_PLATFORM_NAME "PlayStation 5"
#elif BX_PLATFORM_RPI
# define BX_PLATFORM_NAME "RaspberryPi"
#elif BX_PLATFORM_WINDOWS
diff --git a/3rdparty/bx/include/bx/string.h b/3rdparty/bx/include/bx/string.h
index 7b27cc3a103..edb257a6f32 100644
--- a/3rdparty/bx/include/bx/string.h
+++ b/3rdparty/bx/include/bx/string.h
@@ -227,6 +227,12 @@ namespace bx
/// Concatinate string.
int32_t strCat(char* _dst, int32_t _dstSize, const StringView& _str, int32_t _num = INT32_MAX);
+ /// Test whether the string _str begins with prefix.
+ bool hasPrefix(const StringView& _str, const StringView& _prefix);
+
+ /// Test whether the string _str ends with suffix.
+ bool hasSuffix(const StringView& _str, const StringView& _suffix);
+
/// Find character in string. Limit search to _max characters.
StringView strFind(const StringView& _str, char _ch);
diff --git a/3rdparty/bx/tests/math_test.cpp b/3rdparty/bx/tests/math_test.cpp
index d2a36420974..fa3a00d6e4c 100644
--- a/3rdparty/bx/tests/math_test.cpp
+++ b/3rdparty/bx/tests/math_test.cpp
@@ -237,7 +237,7 @@ TEST_CASE("quaternion", "")
float mtxQ[16];
float mtx[16];
- bx::Quaternion quat = { 0.0f, 0.0f, 0.0f, 1.0f };
+ bx::Quaternion quat = bx::init::Identity;
bx::mtxQuat(mtxQ, quat);
bx::mtxIdentity(mtx);
mtxCheck(mtxQ, mtx);
diff --git a/3rdparty/bx/tests/string_test.cpp b/3rdparty/bx/tests/string_test.cpp
index 40f58cf636e..48ee8d83b9a 100644
--- a/3rdparty/bx/tests/string_test.cpp
+++ b/3rdparty/bx/tests/string_test.cpp
@@ -535,3 +535,17 @@ TEST_CASE("strFindBlock", "")
bx::StringView result = bx::strFindBlock(test1, '{', '}');
REQUIRE(19 == result.getLength() );
}
+
+TEST_CASE("hasPrefix", "")
+{
+ REQUIRE( bx::hasPrefix("abvgd-1389.0", "abv") );
+ REQUIRE(!bx::hasPrefix("abvgd-1389.0", "bvg") );
+ REQUIRE( bx::hasPrefix("abvgd-1389.0", "") );
+}
+
+TEST_CASE("hasSuffix", "")
+{
+ REQUIRE( bx::hasSuffix("abvgd-1389.0", "389.0") );
+ REQUIRE(!bx::hasSuffix("abvgd-1389.0", "1389") );
+ REQUIRE( bx::hasSuffix("abvgd-1389.0", "") );
+}
diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua
index 8d43705345a..c39d5f0b21f 100644
--- a/scripts/src/3rdparty.lua
+++ b/scripts/src/3rdparty.lua
@@ -1445,6 +1445,7 @@ end
MAME_DIR .. "3rdparty/bgfx/src/glcontext_html5.cpp",
MAME_DIR .. "3rdparty/bgfx/src/glcontext_wgl.cpp",
MAME_DIR .. "3rdparty/bgfx/src/nvapi.cpp",
+ MAME_DIR .. "3rdparty/bgfx/src/renderer_agc.cpp",
MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d11.cpp",
MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d12.cpp",
MAME_DIR .. "3rdparty/bgfx/src/renderer_d3d9.cpp",