From 0eeb918991d9d9d5acac6eab82fb6b73b9ff71b4 Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Sat, 2 Oct 2021 18:21:12 +0200 Subject: Update bgfx, bx and bimg to latest upstream (fixes issue #8057) (#8645) --- 3rdparty/bgfx/.travis.yml | 36 - 3rdparty/bgfx/3rdparty/cgltf/cgltf.h | 135 ++- 3rdparty/bgfx/3rdparty/cgltf/cgltf_write.h | 43 +- 3rdparty/bgfx/3rdparty/dear-imgui/imgui.cpp | 1161 ++++++++++++-------- 3rdparty/bgfx/3rdparty/dear-imgui/imgui.h | 129 ++- 3rdparty/bgfx/3rdparty/dear-imgui/imgui_demo.cpp | 81 +- 3rdparty/bgfx/3rdparty/dear-imgui/imgui_draw.cpp | 36 +- 3rdparty/bgfx/3rdparty/dear-imgui/imgui_internal.h | 280 ++--- 3rdparty/bgfx/3rdparty/dear-imgui/imgui_tables.cpp | 9 +- .../bgfx/3rdparty/dear-imgui/imgui_widgets.cpp | 251 +++-- 3rdparty/bgfx/3rdparty/glslang/CHANGES.md | 11 + 3rdparty/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.NV.h | 3 + .../bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp | 34 +- .../bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp | 1 + 3rdparty/bgfx/3rdparty/glslang/SPIRV/doc.cpp | 17 + 3rdparty/bgfx/3rdparty/glslang/SPIRV/spirv.hpp | 6 + 3rdparty/bgfx/3rdparty/glslang/build_info.h | 2 +- .../glslang/glslang/HLSL/hlslParseHelper.cpp | 6 +- .../glslang/glslang/HLSL/hlslParseables.cpp | 4 +- .../3rdparty/glslang/glslang/Include/BaseTypes.h | 2 + .../bgfx/3rdparty/glslang/glslang/Include/Common.h | 4 +- .../bgfx/3rdparty/glslang/glslang/Include/Types.h | 10 + .../glslang/glslang/Include/intermediate.h | 2 + .../glslang/MachineIndependent/Constant.cpp | 2 +- .../glslang/MachineIndependent/Initialize.cpp | 62 +- .../glslang/MachineIndependent/Intermediate.cpp | 54 +- .../MachineIndependent/ParseContextBase.cpp | 13 + .../glslang/MachineIndependent/ParseHelper.cpp | 12 +- .../glslang/MachineIndependent/ParseHelper.h | 4 +- .../glslang/MachineIndependent/SymbolTable.cpp | 38 +- .../glslang/MachineIndependent/SymbolTable.h | 29 +- .../glslang/MachineIndependent/Versions.cpp | 7 +- .../glslang/glslang/MachineIndependent/Versions.h | 2 + .../glslang/MachineIndependent/attribute.cpp | 2 +- .../glslang/glslang/MachineIndependent/glslang.m4 | 10 +- .../glslang/glslang/MachineIndependent/glslang.y | 10 +- .../glslang/MachineIndependent/glslang_tab.cpp | 378 +++---- .../glslang/MachineIndependent/intermOut.cpp | 1 + .../glslang/MachineIndependent/iomapper.cpp | 31 + .../glslang/glslang/MachineIndependent/iomapper.h | 16 +- .../glslang/MachineIndependent/linkValidate.cpp | 5 +- .../3rdparty/khronos/vulkan-local/vulkan_beta.h | 95 +- .../3rdparty/khronos/vulkan-local/vulkan_core.h | 135 ++- 3rdparty/bgfx/3rdparty/spirv-cross/spirv_cross.cpp | 4 + 3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp | 60 +- 3rdparty/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp | 2 +- 3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.cpp | 197 +++- 3rdparty/bgfx/3rdparty/spirv-cross/spirv_msl.hpp | 2 + .../3rdparty/spirv-headers/SPIRV-Headers.pc.in | 9 + .../spirv-headers/include/spirv/spir-v.xml | 2 +- .../spirv/unified1/NonSemanticShaderDebugInfo100.h | 171 +++ .../spirv/unified1/NonSemanticVulkanDebugInfo100.h | 171 --- ...t.nonsemantic.shader.debuginfo.100.grammar.json | 713 ++++++++++++ ...t.nonsemantic.vulkan.debuginfo.100.grammar.json | 713 ------------ .../include/spirv/unified1/spirv.core.grammar.json | 101 +- .../spirv-headers/include/spirv/unified1/spirv.cs | 4 + .../spirv-headers/include/spirv/unified1/spirv.h | 6 + .../spirv-headers/include/spirv/unified1/spirv.hpp | 6 + .../include/spirv/unified1/spirv.hpp11 | 6 + .../include/spirv/unified1/spirv.json | 4 + .../spirv-headers/include/spirv/unified1/spirv.lua | 4 + .../spirv-headers/include/spirv/unified1/spirv.py | 4 + .../spirv-headers/include/spirv/unified1/spv.d | 4 + .../generated/NonSemanticShaderDebugInfo100.h | 165 +++ .../generated/NonSemanticVulkanDebugInfo100.h | 165 --- .../include/generated/build-version.inc | 2 +- .../include/generated/core.insts-unified1.inc | 5 +- .../include/generated/enum_string_mapping.inc | 8 +- .../include/generated/extension_enum.inc | 1 + .../spirv-tools/include/generated/generators.inc | 2 +- .../nonsemantic.shader.debuginfo.100.insts.inc | 48 + .../nonsemantic.vulkan.debuginfo.100.insts.inc | 48 - .../include/generated/operand.kinds-unified1.inc | 17 +- .../spirv-tools/include/spirv-tools/libspirv.h | 7 +- .../spirv-tools/include/spirv-tools/libspirv.hpp | 6 + .../spirv-tools/include/spirv-tools/linter.hpp | 2 +- .../spirv-tools/include/spirv-tools/optimizer.hpp | 28 +- .../bgfx/3rdparty/spirv-tools/source/binary.cpp | 3 +- .../spirv-tools/source/common_debug_info.h | 4 +- .../bgfx/3rdparty/spirv-tools/source/ext_inst.cpp | 15 +- ...t.nonsemantic.vulkan.debuginfo.100.grammar.json | 637 ----------- .../source/lint/divergence_analysis.cpp | 245 +++++ .../spirv-tools/source/lint/divergence_analysis.h | 163 +++ .../source/lint/lint_divergent_derivatives.cpp | 169 +++ .../3rdparty/spirv-tools/source/lint/linter.cpp | 21 +- .../bgfx/3rdparty/spirv-tools/source/lint/lints.h | 34 + .../bgfx/3rdparty/spirv-tools/source/operand.cpp | 4 +- .../source/opt/aggressive_dead_code_elim_pass.cpp | 405 +++---- .../source/opt/aggressive_dead_code_elim_pass.h | 73 +- .../spirv-tools/source/opt/block_merge_util.cpp | 4 +- .../spirv-tools/source/opt/compact_ids_pass.cpp | 5 +- .../spirv-tools/source/opt/const_folding_rules.cpp | 4 +- .../3rdparty/spirv-tools/source/opt/constants.cpp | 6 + .../3rdparty/spirv-tools/source/opt/constants.h | 3 + .../source/opt/convert_to_sampled_image_pass.cpp | 437 ++++++++ .../source/opt/convert_to_sampled_image_pass.h | 207 ++++ .../3rdparty/spirv-tools/source/opt/dataflow.cpp | 91 ++ .../3rdparty/spirv-tools/source/opt/dataflow.h | 148 +++ .../spirv-tools/source/opt/debug_info_manager.cpp | 305 +++-- .../spirv-tools/source/opt/debug_info_manager.h | 16 +- .../spirv-tools/source/opt/def_use_manager.cpp | 21 +- .../spirv-tools/source/opt/feature_manager.cpp | 8 +- .../spirv-tools/source/opt/feature_manager.h | 8 +- .../spirv-tools/source/opt/folding_rules.cpp | 225 ++-- .../spirv-tools/source/opt/if_conversion.cpp | 1 + .../spirv-tools/source/opt/inline_pass.cpp | 13 +- .../source/opt/inst_buff_addr_check_pass.cpp | 60 +- .../source/opt/inst_buff_addr_check_pass.h | 12 +- .../spirv-tools/source/opt/instruction.cpp | 80 +- .../3rdparty/spirv-tools/source/opt/instruction.h | 45 +- .../3rdparty/spirv-tools/source/opt/ir_context.cpp | 10 +- .../3rdparty/spirv-tools/source/opt/ir_context.h | 4 + .../3rdparty/spirv-tools/source/opt/ir_loader.cpp | 48 +- .../source/opt/local_access_chain_convert_pass.cpp | 15 + .../source/opt/local_single_block_elim_pass.cpp | 15 + .../source/opt/local_single_store_elim_pass.cpp | 15 + .../spirv-tools/source/opt/loop_unroller.cpp | 6 +- .../3rdparty/spirv-tools/source/opt/module.cpp | 37 +- .../bgfx/3rdparty/spirv-tools/source/opt/module.h | 2 +- .../3rdparty/spirv-tools/source/opt/optimizer.cpp | 62 +- .../bgfx/3rdparty/spirv-tools/source/opt/pass.cpp | 4 +- .../bgfx/3rdparty/spirv-tools/source/opt/passes.h | 1 + .../spirv-tools/source/opt/reduce_load_size.cpp | 5 +- .../spirv-tools/source/opt/reduce_load_size.h | 8 + .../bgfx/3rdparty/spirv-tools/source/opt/reflect.h | 2 +- .../spirv-tools/source/opt/replace_invalid_opc.cpp | 18 +- .../source/opt/scalar_replacement_pass.cpp | 18 +- .../source/opt/scalar_replacement_pass.h | 3 + .../3rdparty/spirv-tools/source/opt/vector_dce.cpp | 32 +- .../3rdparty/spirv-tools/source/opt/vector_dce.h | 7 +- .../spirv-tools/source/spirv_validator_options.cpp | 5 + .../spirv-tools/source/spirv_validator_options.h | 2 + .../3rdparty/spirv-tools/source/util/hex_float.h | 16 +- .../3rdparty/spirv-tools/source/val/construct.cpp | 3 +- .../3rdparty/spirv-tools/source/val/function.cpp | 3 + .../spirv-tools/source/val/validate_adjacency.cpp | 5 +- .../spirv-tools/source/val/validate_atomics.cpp | 2 +- .../spirv-tools/source/val/validate_builtins.cpp | 11 +- .../spirv-tools/source/val/validate_cfg.cpp | 12 + .../source/val/validate_decorations.cpp | 38 +- .../spirv-tools/source/val/validate_extensions.cpp | 1074 ++++++++++-------- .../spirv-tools/source/val/validate_interfaces.cpp | 20 + .../spirv-tools/source/val/validate_layout.cpp | 79 +- .../spirv-tools/source/val/validate_memory.cpp | 6 + .../source/val/validate_mode_setting.cpp | 11 + .../spirv-tools/source/val/validate_type.cpp | 2 +- .../spirv-tools/source/val/validation_state.cpp | 122 +- .../spirv-tools/source/val/validation_state.h | 37 +- 3rdparty/bgfx/CONTRIBUTING.md | 5 +- 3rdparty/bgfx/README.md | 22 +- 3rdparty/bgfx/bindings/bf/bgfx.bf | 5 + 3rdparty/bgfx/bindings/cs/bgfx.cs | 5 + 3rdparty/bgfx/bindings/d/types.d | 1 + 3rdparty/bgfx/examples/18-ibl/ibl.cpp | 4 +- 3rdparty/bgfx/examples/28-wireframe/wireframe.cpp | 8 +- 3rdparty/bgfx/examples/29-debugdraw/debugdraw.cpp | 6 +- 3rdparty/bgfx/examples/36-sky/sky.cpp | 24 +- .../37-gpudrivenrendering/gpudrivenrendering.cpp | 4 +- .../39-assao/cs_assao_generate_importance_map.sc | 2 +- .../bgfx/examples/39-assao/cs_assao_generate_q.sh | 8 +- .../bgfx/examples/39-assao/cs_assao_smart_blur.sc | 8 +- 3rdparty/bgfx/examples/common/bgfx_utils.cpp | 1 + 3rdparty/bgfx/examples/common/bounds.cpp | 204 +++- 3rdparty/bgfx/examples/common/bounds.h | 36 +- 3rdparty/bgfx/examples/common/camera.cpp | 6 +- .../bgfx/examples/common/debugdraw/debugdraw.cpp | 44 +- .../bgfx/examples/common/entry/dialog_darwin.mm | 153 +-- .../bgfx/examples/common/ps/particle_system.cpp | 4 +- 3rdparty/bgfx/include/bgfx/bgfx.h | 1 + 3rdparty/bgfx/include/bgfx/c99/bgfx.h | 21 +- 3rdparty/bgfx/include/bgfx/embedded_shader.h | 132 +-- 3rdparty/bgfx/scripts/bgfx.idl | 7 + 3rdparty/bgfx/scripts/bgfx.lua | 5 + 3rdparty/bgfx/src/amalgamated.cpp | 1 + 3rdparty/bgfx/src/bgfx.cpp | 63 +- 3rdparty/bgfx/src/bgfx_p.h | 85 +- 3rdparty/bgfx/src/bgfx_shader.sh | 54 +- 3rdparty/bgfx/src/config.h | 13 +- 3rdparty/bgfx/src/dxgi.cpp | 8 + 3rdparty/bgfx/src/dxgi.h | 4 + 3rdparty/bgfx/src/renderer_agc.cpp | 20 + 3rdparty/bgfx/src/renderer_d3d11.cpp | 47 +- 3rdparty/bgfx/src/renderer_d3d12.cpp | 37 +- 3rdparty/bgfx/src/renderer_gl.cpp | 61 +- 3rdparty/bgfx/src/renderer_gnm.cpp | 13 +- 3rdparty/bgfx/src/renderer_mtl.mm | 36 +- 3rdparty/bgfx/src/renderer_nvn.cpp | 9 +- 3rdparty/bgfx/src/renderer_vk.cpp | 74 +- 3rdparty/bgfx/src/renderer_vk.h | 22 +- 3rdparty/bgfx/src/vertexlayout.cpp | 1 + 3rdparty/bgfx/tools/geometryc/geometryc.cpp | 30 +- 3rdparty/bgfx/tools/geometryv/geometryv.cpp | 6 +- 3rdparty/bgfx/tools/shaderc/shaderc.cpp | 9 +- 3rdparty/bgfx/tools/shaderc/shaderc_spirv.cpp | 6 + 3rdparty/bimg/.travis.yml | 32 - 3rdparty/bimg/README.md | 1 - 3rdparty/bimg/src/image_cubemap_filter.cpp | 4 +- 3rdparty/bx/.travis.yml | 29 - 3rdparty/bx/README.md | 1 - 3rdparty/bx/include/bx/inline/math.inl | 209 +++- 3rdparty/bx/include/bx/inline/string.inl | 16 + 3rdparty/bx/include/bx/math.h | 94 +- 3rdparty/bx/include/bx/platform.h | 9 + 3rdparty/bx/include/bx/string.h | 6 + 3rdparty/bx/tests/math_test.cpp | 2 +- 3rdparty/bx/tests/string_test.cpp | 14 + scripts/src/3rdparty.lua | 1 + 207 files changed, 8041 insertions(+), 4780 deletions(-) delete mode 100644 3rdparty/bgfx/.travis.yml create mode 100644 3rdparty/bgfx/3rdparty/spirv-headers/SPIRV-Headers.pc.in create mode 100644 3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticShaderDebugInfo100.h delete mode 100644 3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVulkanDebugInfo100.h create mode 100644 3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json delete mode 100644 3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticShaderDebugInfo100.h delete mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/include/generated/NonSemanticVulkanDebugInfo100.h create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc delete mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vulkan.debuginfo.100.insts.inc delete mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.cpp create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/lint/divergence_analysis.h create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lint_divergent_derivatives.cpp create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/lint/lints.h create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.h create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.cpp create mode 100644 3rdparty/bgfx/3rdparty/spirv-tools/source/opt/dataflow.h create mode 100644 3rdparty/bgfx/src/renderer_agc.cpp delete mode 100644 3rdparty/bimg/.travis.yml delete mode 100644 3rdparty/bx/.travis.yml 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 /* For UINT_MAX etc */ #include /* 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 /* 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 #include #include #include @@ -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 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 @@ -1206,6 +1163,70 @@ struct ImGuiPtrOrIndex ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } }; +//----------------------------------------------------------------------------- +// [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 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 ClipboardHandlerData; // If no custom clipboard handler is defined ImVector 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 ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth) ImVector 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 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 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 #ifndef snprintf #define snprintf sprintf_s @@ -214,7 +214,7 @@ template 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(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 } // @@ -3776,6 +3780,28 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node) return false; } +// 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() 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& 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 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& 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 + TVector> 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++) { @@ -319,6 +321,13 @@ public: if (intermediates[stage] != nullptr) 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; @@ -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([&](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(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"); - 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"); - 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"); - 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"); - statement("vec spvFMulVectorMatrix(vec v, matrix m)"); + statement("[[clang::optnone]] vec spvFMulVectorMatrix(vec v, matrix m)"); begin_scope(); statement("vec res = vec(0);"); statement("for (uint i = Rows; i > 0; --i)"); @@ -4948,7 +4972,7 @@ void CompilerMSL::emit_custom_functions() statement(""); statement("template"); - statement("vec spvFMulMatrixVector(matrix m, vec v)"); + statement("[[clang::optnone]] vec spvFMulMatrixVector(matrix m, vec v)"); begin_scope(); statement("vec res = vec(0);"); statement("for (uint i = Cols; i > 0; --i)"); @@ -4960,8 +4984,7 @@ void CompilerMSL::emit_custom_functions() statement(""); statement("template"); - statement( - "matrix spvFMulMatrixMatrix(matrix l, matrix r)"); + statement("[[clang::optnone]] matrix spvFMulMatrixMatrix(matrix l, matrix r)"); begin_scope(); statement("matrix 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"); - 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(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(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(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(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 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 @@ - + 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.shader.debuginfo.100.grammar.json b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json new file mode 100644 index 00000000000..f3621b0b4f8 --- /dev/null +++ b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.shader.debuginfo.100.grammar.json @@ -0,0 +1,713 @@ +{ + "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" : 6, + "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'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "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'" }, + { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } + ] + }, + { + "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'" } + ] + }, + { + "opname" : "DebugSourceContinued", + "opcode" : 102, + "operands" : [ + { "kind" : "IdRef", "name" : "'Text'" } + ] + }, + { + "opname" : "DebugLine", + "opcode" : 103, + "operands" : [ + { "kind" : "IdRef", "name" : "'Source'" }, + { "kind" : "IdRef", "name" : "'Line Start'" }, + { "kind" : "IdRef", "name" : "'Line End'" }, + { "kind" : "IdRef", "name" : "'Column Start'" }, + { "kind" : "IdRef", "name" : "'Column End'" } + ] + }, + { + "opname" : "DebugNoLine", + "opcode" : 104 + }, + { + "opname" : "DebugBuildIdentifier", + "opcode" : 105, + "operands" : [ + { "kind" : "IdRef", "name" : "'Identifier'" }, + { "kind" : "IdRef", "name" : "'Flags'" } + ] + }, + { + "opname" : "DebugStoragePath", + "opcode" : 106, + "operands" : [ + { "kind" : "IdRef", "name" : "'Path'" } + ] + }, + { + "opname" : "DebugEntryPoint", + "opcode" : 107, + "operands" : [ + { "kind" : "IdRef", "name" : "'Entry Point'" }, + { "kind" : "IdRef", "name" : "'Compilation Unit'" }, + { "kind" : "IdRef", "name" : "'Compiler Signature'" }, + { "kind" : "IdRef", "name" : "'Command-line Arguments'" } + ] + }, + { + "opname" : "DebugTypeMatrix", + "opcode" : 108, + "operands" : [ + { "kind" : "IdRef", "name" : "'Vector Type'" }, + { "kind" : "IdRef", "name" : "'Vector Count'" }, + { "kind" : "IdRef", "name" : "'Column Major'" } + ] + } + ], + "operand_kinds" : [ + { + "category" : "BitEnum", + "kind" : "DebugInfoFlags", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "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" + }, + { + "enumerant" : "FlagUnknownPhysicalLayout", + "value" : "0x20000" + } + ] + }, + { + "category" : "BitEnum", + "kind" : "BuildIdentifierFlags", + "enumerants" : [ + { + "enumerant" : "IdentifierPossibleDuplicates", + "value" : "0x01" + } + ] + }, + { + "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-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json b/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json deleted file mode 100644 index f3621b0b4f8..00000000000 --- a/3rdparty/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vulkan.debuginfo.100.grammar.json +++ /dev/null @@ -1,713 +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" : 6, - "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'" }, - { "kind" : "IdRef", "name" : "'Flags'" } - ] - }, - { - "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'" }, - { "kind" : "IdRef", "name" : "'Indexes'", "quantifier" : "*" } - ] - }, - { - "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'" } - ] - }, - { - "opname" : "DebugSourceContinued", - "opcode" : 102, - "operands" : [ - { "kind" : "IdRef", "name" : "'Text'" } - ] - }, - { - "opname" : "DebugLine", - "opcode" : 103, - "operands" : [ - { "kind" : "IdRef", "name" : "'Source'" }, - { "kind" : "IdRef", "name" : "'Line Start'" }, - { "kind" : "IdRef", "name" : "'Line End'" }, - { "kind" : "IdRef", "name" : "'Column Start'" }, - { "kind" : "IdRef", "name" : "'Column End'" } - ] - }, - { - "opname" : "DebugNoLine", - "opcode" : 104 - }, - { - "opname" : "DebugBuildIdentifier", - "opcode" : 105, - "operands" : [ - { "kind" : "IdRef", "name" : "'Identifier'" }, - { "kind" : "IdRef", "name" : "'Flags'" } - ] - }, - { - "opname" : "DebugStoragePath", - "opcode" : 106, - "operands" : [ - { "kind" : "IdRef", "name" : "'Path'" } - ] - }, - { - "opname" : "DebugEntryPoint", - "opcode" : 107, - "operands" : [ - { "kind" : "IdRef", "name" : "'Entry Point'" }, - { "kind" : "IdRef", "name" : "'Compilation Unit'" }, - { "kind" : "IdRef", "name" : "'Compiler Signature'" }, - { "kind" : "IdRef", "name" : "'Command-line Arguments'" } - ] - }, - { - "opname" : "DebugTypeMatrix", - "opcode" : 108, - "operands" : [ - { "kind" : "IdRef", "name" : "'Vector Type'" }, - { "kind" : "IdRef", "name" : "'Vector Count'" }, - { "kind" : "IdRef", "name" : "'Column Major'" } - ] - } - ], - "operand_kinds" : [ - { - "category" : "BitEnum", - "kind" : "DebugInfoFlags", - "enumerants" : [ - { - "enumerant" : "None", - "value" : "0x0000" - }, - { - "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" - }, - { - "enumerant" : "FlagUnknownPhysicalLayout", - "value" : "0x20000" - } - ] - }, - { - "category" : "BitEnum", - "kind" : "BuildIdentifierFlags", - "enumerants" : [ - { - "enumerant" : "IdentifierPossibleDuplicates", - "value" : "0x01" - } - ] - }, - { - "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-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 @@ -4753,6 +4753,52 @@ "extensions" : [ "SPV_NV_ray_tracing" ], "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", @@ -7630,24 +7676,6 @@ "capabilities" : [ "ArbitraryPrecisionFloatingPointINTEL" ], "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", @@ -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" } ] }, @@ -12052,6 +12077,13 @@ "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, + { + "enumerant" : "CurrentRayTimeNV", + "value" : 5334, + "capabilities" : [ "RayTracingMotionBlurNV" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, { "enumerant" : "IncomingRayFlagsNV", "value" : 5351, @@ -13084,6 +13116,13 @@ "extensions" : [ "SPV_NV_ray_tracing" ], "version" : "None" }, + { + "enumerant" : "RayTracingMotionBlurNV", + "value" : 5341, + "capabilities" : [ "Shader" ], + "extensions" : [ "SPV_NV_ray_tracing_motion_blur" ], + "version" : "None" + }, { "enumerant" : "VulkanMemoryModel", "value" : 5345, 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.shader.debuginfo.100.insts.inc b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc new file mode 100644 index 00000000000..27ce78fa94f --- /dev/null +++ b/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.shader.debuginfo.100.insts.inc @@ -0,0 +1,48 @@ + + +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}}, + {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypedef", 7, 0, nullptr, {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_NONE}}, + {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeEnum", 9, 0, nullptr, {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_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeComposite", 10, 0, nullptr, {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_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMember", 11, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameter", 15, 0, nullptr, {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_NONE}}, + {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugGlobalVariable", 18, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDeclaration", 19, 0, nullptr, {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_NONE}}, + {"DebugFunction", 20, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLocalVariable", 26, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugImportedEntity", 34, 0, nullptr, {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_NONE}}, + {"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugFunctionDefinition", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugSourceContinued", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugLine", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugNoLine", 104, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, + {"DebugBuildIdentifier", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugStoragePath", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugEntryPoint", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"DebugTypeMatrix", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file 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.vulkan.debuginfo.100.insts.inc deleted file mode 100644 index dff31513538..00000000000 --- a/3rdparty/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vulkan.debuginfo.100.insts.inc +++ /dev/null @@ -1,48 +0,0 @@ - - -static const spv_ext_inst_desc_t nonsemantic_vulkan_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}}, - {"DebugTypePointer", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeQualifier", 4, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeArray", 5, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeVector", 6, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypedef", 7, 0, nullptr, {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_NONE}}, - {"DebugTypeFunction", 8, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeEnum", 9, 0, nullptr, {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_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeComposite", 10, 0, nullptr, {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_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeMember", 11, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeInheritance", 12, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypePtrToMember", 13, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeTemplate", 14, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeTemplateParameter", 15, 0, nullptr, {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_NONE}}, - {"DebugTypeTemplateTemplateParameter", 16, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeTemplateParameterPack", 17, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugGlobalVariable", 18, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugFunctionDeclaration", 19, 0, nullptr, {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_NONE}}, - {"DebugFunction", 20, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugLexicalBlock", 21, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugLexicalBlockDiscriminator", 22, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugScope", 23, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugNoScope", 24, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, - {"DebugInlinedAt", 25, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugLocalVariable", 26, 0, nullptr, {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_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugInlinedVariable", 27, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugDeclare", 28, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugValue", 29, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugOperation", 30, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugExpression", 31, 0, nullptr, {SPV_OPERAND_TYPE_VARIABLE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugMacroDef", 32, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugMacroUndef", 33, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugImportedEntity", 34, 0, nullptr, {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_NONE}}, - {"DebugSource", 35, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugFunctionDefinition", 101, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugSourceContinued", 102, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugLine", 103, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugNoLine", 104, 0, nullptr, {SPV_OPERAND_TYPE_NONE}}, - {"DebugBuildIdentifier", 105, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugStoragePath", 106, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugEntryPoint", 107, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, - {"DebugTypeMatrix", 108, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}} -}; \ No newline at end of file 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 #include #include +#include #include #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& + 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(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 << ""; + } +} + +} // 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 +#include +#include + +#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 divergence_; + std::unordered_map divergence_source_; + std::unordered_map 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 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 +#include +#include + +#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 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 spvOperandCanBeForwardDeclaredFunction( std::function 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(&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& structuredOrder) { - block2headerBranch_.clear(); - header2nextHeaderBranch_.clear(); - branch2merge_.clear(); - structured_order_index_.clear(); - std::stack 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 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(param)); - }, - false); + MarkFunctionParameterAsLive(func); - // Compute map from block to controlling conditional branch std::list 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 assume_branches_live; - std::stack 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& 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 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 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 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(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*(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& 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& 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 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 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 header2nextHeaderBranch_; - - // Maps basic block to their index in the structured order traversal. - std::unordered_map structured_order_index_; - - // Map from branch to its associated merge instruction, if any - std::unordered_map branch2merge_; - - // Store instructions to variables of private storage - std::vector 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(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& 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 Constant::GetVectorComponents( analysis::ConstantManager* const_mgr) const { std::vector 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 +#include +#include + +#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; +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* 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* 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 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 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 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 sampler_variable_loads; + FindUses(sampler_variable, &sampler_variable_loads, SpvOpLoad); + for (auto* load : sampler_variable_loads) { + std::vector 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 +ConvertToSampledImagePass::ParseDescriptorSetBindingPairsString( + const char* str) { + if (!str) return nullptr; + + auto descriptor_set_binding_pairs = + MakeUnique(); + + 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 +#include +#include + +#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()(descriptor_set_binding.descriptor_set) ^ + std::hash()(descriptor_set_binding.binding); + } + }; + + using SetOfDescriptorSetAndBindingPairs = + std::unordered_set; + using DescriptorSetBindingToInstruction = + std::unordered_map; + + explicit ConvertToSampledImagePass( + const std::vector& 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: + // + // ": : ..." + // 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. + // + // : the descriptor set. + // The text must represent a valid uint32_t number. + // + // : the binding. + // The text must represent a valid uint32_t number. + static std::unique_ptr> + 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* 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* 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 +#include + +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 +#include +#include + +#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 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 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(OpenCLDebugInfo100DebugInlinedAt)}}, - {spv_operand_type_t::SPV_OPERAND_TYPE_LITERAL_INTEGER, {line_number}}, + {static_cast(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 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(OpenCLDebugInfo100DebugOperation)}}, - {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, - {static_cast(OpenCLDebugInfo100Deref)}}, - })); + std::unique_ptr deref_operation; + + if (context()->get_feature_mgr()->GetExtInstImportId_OpenCL100DebugInfo()) { + deref_operation = std::unique_ptr(new Instruction( + context(), SpvOpExtInst, context()->get_type_mgr()->GetVoidTypeId(), + result_id, + { + {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast(OpenCLDebugInfo100DebugOperation)}}, + {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION, + {static_cast(OpenCLDebugInfo100Deref)}}, + })); + } else { + uint32_t deref_id = context()->get_constant_mgr()->GetUIntConst( + NonSemanticShaderDebugInfo100Deref); + + deref_operation = std::unique_ptr( + new Instruction(context(), SpvOpExtInst, + context()->get_type_mgr()->GetVoidTypeId(), result_id, + { + {SPV_OPERAND_TYPE_ID, {GetDbgSetImportId()}}, + {SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, + {static_cast( + 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 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(OpenCLDebugInfo100DebugInfoNone)}}, + {static_cast(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(OpenCLDebugInfo100DebugExpression)}}, + {static_cast(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 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(OpenCLDebugInfo100DebugDeclare)}}, + {static_cast(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 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 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 #include #include #include @@ -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 words; -#define FOLD_OP(op) \ - if (width == 64) { \ - if (type->IsSigned()) { \ - int64_t val = input1->GetS64() op input2->GetS64(); \ - words = ExtractInts(static_cast(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(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& 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&) { - // 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 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 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 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&) { + // 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 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 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 -#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 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&& 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 #include -#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 { // 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& 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 { // 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 { // 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 { 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 { 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 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* to_kill) { if (!inst->HasResultId()) return; + // Debug[No]Line result id is not used, so we are done + if (inst->IsDebugLineInst()) return; std::vector work_list; std::unordered_set 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 decoration_mgr_; + + // The feature manager for |module_|. std::unique_ptr 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 #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(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(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(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( 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( + 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(&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(&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(&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* 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* 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(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(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(SpvOpNoLine)); + } last_line_inst = nullptr; } } @@ -181,7 +191,7 @@ void Module::ToBinary(std::vector* 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* 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* 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 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 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 : 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()); } -Optimizer::PassToken CreateAggressiveDCEPass() { +Optimizer::PassToken CreateAggressiveDCEPass(bool preserve_interface) { return MakeUnique( - MakeUnique()); + MakeUnique(preserve_interface)); } Optimizer::PassToken CreateRemoveUnusedInterfaceVariablesPass() { @@ -859,9 +895,10 @@ Optimizer::PassToken CreateVectorDCEPass() { return MakeUnique(MakeUnique()); } -Optimizer::PassToken CreateReduceLoadSizePass() { +Optimizer::PassToken CreateReduceLoadSizePass( + double load_replacement_threshold) { return MakeUnique( - MakeUnique()); + MakeUnique(load_replacement_threshold)); } Optimizer::PassToken CreateCombineAccessChainsPass() { @@ -940,4 +977,11 @@ Optimizer::PassToken CreateInterpolateFixupPass() { MakeUnique()); } +Optimizer::PassToken CreateConvertToSampledImagePass( + const std::vector& + descriptor_set_binding_pairs) { + return MakeUnique( + MakeUnique(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(elements_used.size()) / static_cast(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 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( &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* 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& 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& 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& 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(written_exponent * 10); written_exponent = @@ -1059,6 +1068,11 @@ std::istream& operator>>(std::istream& is, HexFloat& 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(written_exponent * exponent_sign); exponent = static_cast(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(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 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 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 hasOffset; + std::vector 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(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(1) != 32) { + return false; + } + + return !must_unsigned || type->GetOperandAs(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& 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& expectation, + const std::function& 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& ext_inst_name) { - std::function expectation = - [expected_debug_inst](OpenCLDebugInfo100Instructions dbg_inst) { + std::function 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& 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& ext_inst_name) { - std::function expectation = - [](OpenCLDebugInfo100Instructions dbg_inst) { - return dbg_inst == OpenCLDebugInfo100DebugCompilationUnit || - dbg_inst == OpenCLDebugInfo100DebugFunction || - dbg_inst == OpenCLDebugInfo100DebugLexicalBlock || - dbg_inst == OpenCLDebugInfo100DebugTypeComposite; + std::function 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& ext_inst_name, bool allow_template_param) { - std::function expectation = - [&allow_template_param](OpenCLDebugInfo100Instructions dbg_inst) { + std::function 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(1) != 32) { - return false; - } - - if (type->GetOperandAs(2) != 0) { - return false; - } - - return true; -} - spv_result_t ValidateClspvReflectionKernel(ValidationState_t& _, const Instruction* inst) { const auto kernel_id = inst->GetOperandAs(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(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 input_locations; std::unordered_set output_locations_index0; std::unordered_set output_locations_index1; + std::unordered_set seen; for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { auto interface_id = entry_point->GetOperandAs(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 #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(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 '" << _.getIdName(rows_id) + << "OpTypeCooperativeMatrixNV Cols '" << _.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& f, + bool traverse_all_types) const { const auto inst = FindDef(id); if (!inst) return false; - if (inst->opcode() == type) { - return inst->GetOperandAs(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(1u), type, - width); + return ContainsType(inst->GetOperandAs(1u), f, + traverse_all_types); case SpvOpTypePointer: if (IsForwardPointer(id)) return false; - return ContainsSizedIntOrFloatType(inst->GetOperandAs(2u), type, - width); + if (traverse_all_types) { + return ContainsType(inst->GetOperandAs(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(i), type, - width)) + if (ContainsType(inst->GetOperandAs(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(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& 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 @@ License

-[![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/ + + + +## 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 @@ -1334,6 +1334,11 @@ public static class bgfx /// Noop, + /// + /// AGC + /// + Agc, + /// /// Direct3D 9.0 /// 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 @@ -1331,6 +1331,11 @@ public static partial class bgfx /// Noop, + /// + /// AGC + /// + Agc, + /// /// Direct3D 9.0 /// 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 sunLuminanceXYZTable = { + static std::map 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 skyLuminanceXYZTable = { + static std::map 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(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(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 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(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 @@ -99,6 +99,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, ®ion); 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(m_width) >> _mip, 1); int32_t mipHeight = bx::max(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(surfaceCapabilities.minImageCount, 2); const uint32_t maxSwapBufferCount = surfaceCapabilities.maxImageCount == 0 - ? BGFX_CONFIG_MAX_BACK_BUFFERS - : bx::min(surfaceCapabilities.maxImageCount, BGFX_CONFIG_MAX_BACK_BUFFERS) + ? kMaxBackBuffers + : bx::min(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;vm_normals.reserve(_mesh->m_normals.size() + accessorCount); hasNormal = true; - bx::Vec3 normal; - for (cgltf_size v=0;vm_texcoords.reserve(_mesh->m_texcoords.size() + accessorCount); hasTexcoord = true; - bx::Vec3 texcoord; - for (cgltf_size v=0;vm_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 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); /// @@ -396,6 +465,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); @@ -408,9 +486,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", -- cgit v1.2.3