diff --git a/AUTHORS.md b/AUTHORS.md index 1ae22e1..ca091ff 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -13,4 +13,4 @@ contributed to the project prior to the project being hosted on GitHub. See the GitHub commit log for a list of recent contributors. We would like to thank everyone who has contributed to the project in any way. -* __[Sam Loeschen](https://github.com/samloeschen)__ \ No newline at end of file +* __[Sam Loeschen](https://github.com/samloeschen)__ diff --git a/README.md b/README.md index 61aa4db..ad92b9b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ When [zig](https://github.com/ziglang/zig) meets [bgfx](https://github.com/bkara - [x] `shaderc` as build artifact. - [x] Shader compile in `build.zig` to `*.bin.h`. - [x] Shader compile in `build.zig` and embed as zig module. (this is zig equivalent of `*.bin.h`) -- [x] Shader compile from code (in memory solution, no tmp files). +- [ ] Shader compile from runtime via `shaderc` as child process. +- [x] Experimental shader compile from runtime via embeded `shaderc`. - [x] Binding for [DebugDraw API](https://github.com/bkaradzic/bgfx/tree/master/examples/common/debugdraw) - [x] `imgui` render backend. Use build option `imgui_include` to enable. ex. for zgui: `.imgui_include = zgui.path("libs").getPath(b),` @@ -38,6 +39,12 @@ Zig binding is licensed by [WTFPL](LICENSE) Minimal is `0.13.0`. But you know try your version and believe. +## Bgfx version + +- [BX](https://github.com/bkaradzic/bx/commit/e7ede513dc8b90386960587e348c73b241f7735d) +- [BImg](https://github.com/bkaradzic/bimg/commit/2afa64c14c1e3dd5d28412ee03bee0dfe7242f03) +- [BGFX](https://github.com/bkaradzic/bgfx/commit/74e7edccdc340a56e862c1234626dbb276e88553) + ## Getting started Copy `zbgfx` to a subdirectory of your project and add the following to your `build.zig.zon` .dependencies: diff --git a/build.zig b/build.zig index 0e8bd89..3e445a1 100644 --- a/build.zig +++ b/build.zig @@ -41,6 +41,8 @@ pub fn build(b: *std.Build) !void { "-Wno-microsoft-enum-value", "-Wno-microsoft-const-init", + "-Wno-deprecated-declarations", + "-Wno-tautological-constant-compare", }; const cxx_options = common_options ++ [_][]const u8{ "-std=c++17", @@ -921,6 +923,7 @@ const spirv_opt_files = .{ spirv_opt_path ++ "source/opt/vector_dce.cpp", spirv_opt_path ++ "source/opt/workaround1209.cpp", spirv_opt_path ++ "source/opt/wrap_opkill.cpp", + spirv_opt_path ++ "source/opt/opextinst_forward_ref_fixup_pass.cpp", spirv_opt_path ++ "source/parsed_operand.cpp", spirv_opt_path ++ "source/print.cpp", spirv_opt_path ++ "source/reduce/change_operand_reduction_opportunity.cpp", diff --git a/libs/bgfx/3rdparty/.editorconfig b/libs/bgfx/3rdparty/.editorconfig new file mode 100644 index 0000000..ca5c357 --- /dev/null +++ b/libs/bgfx/3rdparty/.editorconfig @@ -0,0 +1,37 @@ +root = true + +[etc1/*] +indent_style = space +indent_size = 4 + +[fcpp/*] +indent_style = space +indent_size = 2 + +[iqa/*] +indent_style = tab +indent_size = 4 + +[libsquish/*] +indent_style = tab +indent_size = 4 + +[dear-imgui/*] +indent_style = space +indent_size = 4 + +[dear-imgui/*.inl] +indent_style = space +indent_size = 4 + +[pvrtc/*] +indent_style = space +indent_size = 4 + +[remotery/*] +indent_style = space +indent_size = 4 + +[glsl-optimizer/*] +indent_style = space +indent_size = 3 diff --git a/libs/bgfx/3rdparty/cgltf/cgltf.h b/libs/bgfx/3rdparty/cgltf/cgltf.h index f6d01cd..ac392ab 100644 --- a/libs/bgfx/3rdparty/cgltf/cgltf.h +++ b/libs/bgfx/3rdparty/cgltf/cgltf.h @@ -1,7 +1,7 @@ /** * cgltf - a single-file glTF 2.0 parser written in C99. * - * Version: 1.13 + * Version: 1.14 * * Website: https://github.com/jkuhlmann/cgltf * @@ -505,6 +505,11 @@ typedef struct cgltf_anisotropy cgltf_texture_view anisotropy_texture; } cgltf_anisotropy; +typedef struct cgltf_dispersion +{ + cgltf_float dispersion; +} cgltf_dispersion; + typedef struct cgltf_material { char* name; @@ -519,6 +524,7 @@ typedef struct cgltf_material cgltf_bool has_emissive_strength; cgltf_bool has_iridescence; cgltf_bool has_anisotropy; + cgltf_bool has_dispersion; cgltf_pbr_metallic_roughness pbr_metallic_roughness; cgltf_pbr_specular_glossiness pbr_specular_glossiness; cgltf_clearcoat clearcoat; @@ -530,6 +536,7 @@ typedef struct cgltf_material cgltf_emissive_strength emissive_strength; cgltf_iridescence iridescence; cgltf_anisotropy anisotropy; + cgltf_dispersion dispersion; cgltf_texture_view normal_texture; cgltf_texture_view occlusion_texture; cgltf_texture_view emissive_texture; @@ -1690,7 +1697,20 @@ cgltf_result cgltf_validate(cgltf_data* data) { if (data->nodes[i].weights && data->nodes[i].mesh) { - CGLTF_ASSERT_IF (data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->nodes[i].mesh->primitives_count && data->nodes[i].mesh->primitives[0].targets_count != data->nodes[i].weights_count, cgltf_result_invalid_gltf); + } + + if (data->nodes[i].has_mesh_gpu_instancing) + { + CGLTF_ASSERT_IF(data->nodes[i].mesh == NULL, cgltf_result_invalid_gltf); + CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes_count == 0, cgltf_result_invalid_gltf); + + cgltf_accessor* first = data->nodes[i].mesh_gpu_instancing.attributes[0].data; + + for (cgltf_size k = 0; k < data->nodes[i].mesh_gpu_instancing.attributes_count; ++k) + { + CGLTF_ASSERT_IF(data->nodes[i].mesh_gpu_instancing.attributes[k].data->count != first->count, cgltf_result_invalid_gltf); + } } } @@ -4297,6 +4317,37 @@ static int cgltf_parse_json_anisotropy(cgltf_options* options, jsmntok_t const* return i; } +static int cgltf_parse_json_dispersion(jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_dispersion* out_dispersion) +{ + CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i].size; + ++i; + + + for (int j = 0; j < size; ++j) + { + CGLTF_CHECK_KEY(tokens[i]); + + if (cgltf_json_strcmp(tokens + i, json_chunk, "dispersion") == 0) + { + ++i; + out_dispersion->dispersion = cgltf_json_to_float(tokens + i, json_chunk); + ++i; + } + else + { + i = cgltf_skip_json(tokens, i + 1); + } + + if (i < 0) + { + return i; + } + } + + return i; +} + static int cgltf_parse_json_image(cgltf_options* options, jsmntok_t const* tokens, int i, const uint8_t* json_chunk, cgltf_image* out_image) { CGLTF_CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); @@ -4690,6 +4741,11 @@ static int cgltf_parse_json_material(cgltf_options* options, jsmntok_t const* to out_material->has_anisotropy = 1; i = cgltf_parse_json_anisotropy(options, tokens, i + 1, json_chunk, &out_material->anisotropy); } + else if (cgltf_json_strcmp(tokens + i, json_chunk, "KHR_materials_dispersion") == 0) + { + out_material->has_dispersion = 1; + i = cgltf_parse_json_dispersion(tokens, i + 1, json_chunk, &out_material->dispersion); + } else { i = cgltf_parse_json_unprocessed_extension(options, tokens, i, json_chunk, &(out_material->extensions[out_material->extensions_count++])); diff --git a/libs/bgfx/3rdparty/cgltf/cgltf_write.h b/libs/bgfx/3rdparty/cgltf/cgltf_write.h index 0c6da06..aa648a4 100644 --- a/libs/bgfx/3rdparty/cgltf/cgltf_write.h +++ b/libs/bgfx/3rdparty/cgltf/cgltf_write.h @@ -1,7 +1,7 @@ /** * cgltf_write - a single-file glTF 2.0 writer written in C99. * - * Version: 1.13 + * Version: 1.14 * * Website: https://github.com/jkuhlmann/cgltf * @@ -86,6 +86,7 @@ cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size si #define CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING (1 << 14) #define CGLTF_EXTENSION_FLAG_MATERIALS_IRIDESCENCE (1 << 15) #define CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY (1 << 16) +#define CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION (1 << 17) typedef struct { char* buffer; @@ -659,6 +660,11 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_ANISOTROPY; } + if (material->has_dispersion) + { + context->extension_flags |= CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION; + } + if (material->has_pbr_metallic_roughness) { const cgltf_pbr_metallic_roughness* params = &material->pbr_metallic_roughness; @@ -674,7 +680,7 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater cgltf_write_line(context, "}"); } - if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy) + if (material->unlit || material->has_pbr_specular_glossiness || material->has_clearcoat || material->has_ior || material->has_specular || material->has_transmission || material->has_sheen || material->has_volume || material->has_emissive_strength || material->has_iridescence || material->has_anisotropy || material->has_dispersion) { cgltf_write_line(context, "\"extensions\": {"); if (material->has_clearcoat) @@ -794,6 +800,13 @@ static void cgltf_write_material(cgltf_write_context* context, const cgltf_mater CGLTF_WRITE_TEXTURE_INFO("anisotropyTexture", params->anisotropy_texture); cgltf_write_line(context, "}"); } + if (material->has_dispersion) + { + cgltf_write_line(context, "\"KHR_materials_dispersion\": {"); + const cgltf_dispersion* params = &material->dispersion; + cgltf_write_floatprop(context, "dispersion", params->dispersion, 0.f); + cgltf_write_line(context, "}"); + } cgltf_write_line(context, "}"); } @@ -1279,6 +1292,9 @@ static void cgltf_write_extensions(cgltf_write_context* context, uint32_t extens if (extension_flags & CGLTF_EXTENSION_FLAG_MESH_GPU_INSTANCING) { cgltf_write_stritem(context, "EXT_mesh_gpu_instancing"); } + if (extension_flags & CGLTF_EXTENSION_FLAG_MATERIALS_DISPERSION) { + cgltf_write_stritem(context, "KHR_materials_dispersion"); + } } cgltf_size cgltf_write(const cgltf_options* options, char* buffer, cgltf_size size, const cgltf_data* data) diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui.cpp b/libs/bgfx/3rdparty/dear-imgui/imgui.cpp index c07588b..247f8dd 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui.cpp +++ b/libs/bgfx/3rdparty/dear-imgui/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (main code and documentation) // Help: @@ -7,15 +7,19 @@ // - Read top of imgui.cpp for more details, links and comments. // Resources: -// - FAQ https://dearimgui.com/faq -// - Getting Started https://dearimgui.com/getting-started -// - Homepage https://github.com/ocornut/imgui -// - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/6897 (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 -// - Tests & Automation https://github.com/ocornut/imgui_test_engine +// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md) +// - Homepage ................... https://github.com/ocornut/imgui +// - Releases & changelog ....... https://github.com/ocornut/imgui/releases +// - Gallery .................... https://github.com/ocornut/imgui/issues/7503 (please post your screenshots/video there!) +// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code) +// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more) +// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines) +// - Glossary https://github.com/ocornut/imgui/wiki/Glossary +// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools +// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui +// - Issues & support ........... https://github.com/ocornut/imgui/issues +// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps) // For first-time users having issues compiling/linking/running/loading fonts: // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. @@ -26,7 +30,7 @@ // See LICENSE.txt for copyright and licensing details (standard MIT License). // This library is free but needs your support to sustain development and maintenance. // Businesses: you can support continued development via B2B invoiced technical support, maintenance and sponsoring contracts. -// PLEASE reach out at omar AT dearimgui DOT com. See https://github.com/ocornut/imgui/wiki/Sponsors +// PLEASE reach out at omar AT dearimgui DOT com. See https://github.com/ocornut/imgui/wiki/Funding // Businesses: you can also purchase licenses for the Dear ImGui Automation/Test Engine. // It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library. @@ -73,6 +77,7 @@ CODE // [SECTION] RENDER HELPERS // [SECTION] INITIALIZATION, SHUTDOWN // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) +// [SECTION] ID STACK // [SECTION] INPUTS // [SECTION] ERROR CHECKING // [SECTION] ITEM SUBMISSION @@ -138,7 +143,7 @@ CODE - CTRL+X, CTRL+C, CTRL+V: Use OS clipboard. - CTRL+Z, CTRL+Y: Undo, Redo. - ESCAPE: Revert text to its original value. - - On OSX, controls are automatically adjusted to match standard OSX text editing shortcuts and behaviors. + - On OSX, controls are automatically adjusted to match standard OSX text editing 2ts and behaviors. - KEYBOARD CONTROLS - Basic: @@ -425,6 +430,39 @@ 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. + - 2024/06/10 (1.90.9) - removed old nested structure: renaming ImGuiStorage::ImGuiStoragePair type to ImGuiStoragePair (simpler for many languages). + - 2024/06/06 (1.90.8) - reordered ImGuiInputTextFlags values. This should not be breaking unless you are using generated headers that have values not matching the main library. + - 2024/06/06 (1.90.8) - removed 'ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft', was mostly unused and misleading. + - 2024/05/27 (1.90.7) - commented out obsolete symbols marked obsolete in 1.88 (May 2022): + - old: CaptureKeyboardFromApp(bool) + - new: SetNextFrameWantCaptureKeyboard(bool) + - old: CaptureMouseFromApp(bool) + - new: SetNextFrameWantCaptureMouse(bool) + - 2024/05/22 (1.90.7) - inputs (internals): renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner, to make use more explicit and reduce confusion with the default it is a non-zero value and cannot be the default value (never made public, but disclosing as I expect a few users caught on owner-aware inputs). + - inputs (internals): renamed ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal, ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobalOverFocused, ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobalHighest. + - inputs (internals): Shortcut(), SetShortcutRouting(): swapped last two parameters order in function signatures: + - old: Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); + - new: Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0, ImGuiID owner_id = 0); + - inputs (internals): owner-aware versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(): swapped last two parameters order in function signatures. + - old: IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); + - new: IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0); + - old: IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0); + - new: IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id = 0); + for various reasons those changes makes sense. They are being made because making some of those API public. + only past users of imgui_internal.h with the extra parameters will be affected. Added asserts for valid flags in various functions to detect _some_ misuses, BUT NOT ALL. + - 2024/05/16 (1.90.7) - inputs: on macOS X, Cmd and Ctrl keys are now automatically swapped by io.AddKeyEvent() as this naturally align with how macOS X uses those keys. + - it shouldn't really affect you unless you had custom shortcut swapping in place for macOS X apps. + - removed ImGuiMod_Shortcut which was previously dynamically remapping to Ctrl or Cmd/Super. It is now unnecessary to specific cross-platform idiomatic shortcuts. (#2343, #4084, #5923, #456) + - 2024/05/14 (1.90.7) - backends: SDL_Renderer2 and SDL_Renderer3 backend now take a SDL_Renderer* in their RenderDrawData() functions. + - 2024/04/18 (1.90.6) - TreeNode: Fixed a layout inconsistency when using an empty/hidden label followed by a SameLine() call. (#7505, #282) + - old: TreeNode("##Hidden"); SameLine(); Text("Hello"); // <-- This was actually incorrect! BUT appeared to look ok with the default style where ItemSpacing.x == FramePadding.x * 2 (it didn't look aligned otherwise). + - new: TreeNode("##Hidden"); SameLine(0, 0); Text("Hello"); // <-- This is correct for all styles values. + with the fix, IF you were successfully using TreeNode("")+SameLine(); you will now have extra spacing between your TreeNode and the following item. + You'll need to change the SameLine() call to SameLine(0,0) to remove this extraneous spacing. This seemed like the more sensible fix that's not making things less consistent. + (Note: when using this idiom you are likely to also use ImGuiTreeNodeFlags_SpanAvailWidth). + - 2024/03/18 (1.90.5) - merged the radius_x/radius_y parameters in ImDrawList::AddEllipse(), AddEllipseFilled() and PathEllipticalArcTo() into a single ImVec2 parameter. Exceptionally, because those functions were added in 1.90, we are not adding inline redirection functions. The transition is easy and should affect few users. (#2743, #7417) + - 2024/03/08 (1.90.5) - inputs: more formally obsoleted GetKeyIndex() when IMGUI_DISABLE_OBSOLETE_FUNCTIONS is set. It has been unnecessary and a no-op since 1.87 (it returns the same value as passed when used with a 1.87+ backend using io.AddKeyEvent() function). (#4921) + - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) - 2024/01/15 (1.90.2) - commented out obsolete ImGuiIO::ImeWindowHandle marked obsolete in 1.87, favor of writing to 'void* ImGuiViewport::PlatformHandleRaw'. - 2023/12/19 (1.90.1) - commented out obsolete ImGuiKey_KeyPadEnter redirection to ImGuiKey_KeypadEnter. - 2023/11/06 (1.90.1) - removed CalcListClipping() marked obsolete in 1.86. Prefer using ImGuiListClipper which can return non-contiguous ranges. @@ -537,7 +575,7 @@ CODE - Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only] note: for all calls to IO new functions, the Dear ImGui context should be bound/current. read https://github.com/ocornut/imgui/issues/4921 for details. - - 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details. + - 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unnecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details. - IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX) - IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX) - Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() (+ call io.SetKeyEventNativeData() if you want legacy user code to stil function with legacy key codes). @@ -935,7 +973,7 @@ CODE A: - Businesses: please reach out to "omar AT dearimgui DOT com" if you work in a place using Dear ImGui! We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts. This is among the most useful thing you can do for Dear ImGui. With increased funding, we sustain and grow work on this project. - Also see https://github.com/ocornut/imgui/wiki/Sponsors + >>> See https://github.com/ocornut/imgui/wiki/Funding - Businesses: you can also purchase licenses for the Dear ImGui Automation/Test Engine. - If you are experienced with Dear ImGui and C++, look at the GitHub issues, look at the Wiki, and see how you want to help and can help! - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. @@ -986,7 +1024,8 @@ CODE #else #include #endif -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) // UWP doesn't have all Win32 functions +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES) +// The UWP and GDK Win32 API subsets don't support clipboard nor IME functions #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS #define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS #endif @@ -1028,6 +1067,7 @@ CODE #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0 #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) // We disable -Wpragmas because GCC doesn't provide a has_warning equivalent and some forks/patches may not follow the warning/version association. #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind @@ -1064,7 +1104,6 @@ static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multi //------------------------------------------------------------------------- static void SetCurrentWindow(ImGuiWindow* window); -static void FindHoveredWindow(); static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); @@ -1084,6 +1123,9 @@ static void SetPlatformImeDataFn_DefaultImpl(ImGuiViewport* viewport namespace ImGui { +// Item +static void ItemHandleShortcut(ImGuiID id); + // Navigation static void NavUpdate(); static void NavUpdateWindowing(); @@ -1126,6 +1168,7 @@ static void RenderWindowDecorations(ImGuiWindow* window, const ImRec static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col); static void RenderDimmedBackgrounds(); +static void SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect); // Viewports const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter. @@ -1181,58 +1224,59 @@ static void* GImAllocatorUserData = NULL; ImGuiStyle::ImGuiStyle() { - 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. - WindowMinSize = ImVec2(32,32); // Minimum window size - WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text - WindowMenuButtonPosition= ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left. - ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows - ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. - PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows - PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. - FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) - FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). - FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. - ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines - ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - CellPadding = ImVec2(4,2); // Padding within a table cell. CellPadding.y may be altered between different rows. - TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). - ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). - ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar - ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar - GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar - GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. - LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. - TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. - TabBorderSize = 0.0f; // Thickness of border around tabs. - TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. - TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. - TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees). - ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. - ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. - SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. - SeparatorTextBorderSize = 3.0f; // Thickkness of border in SeparatorText() - SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). - SeparatorTextPadding = ImVec2(20.0f,3.f);// Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. - DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. - DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. - MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. - AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. - AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). - AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). - CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. + 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. + WindowMinSize = ImVec2(32,32); // Minimum window size + WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text + WindowMenuButtonPosition = ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left. + ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. + PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. + FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) + FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. + ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines + ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + CellPadding = ImVec2(4,2); // Padding within a table cell. Cellpadding.x is locked for entire table. CellPadding.y may be altered between different rows. + TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). + ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar + ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar + GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar + GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero. + TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. + TabBorderSize = 0.0f; // Thickness of border around tabs. + TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. + TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees). + TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell + ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. + ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. + SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. + SeparatorTextBorderSize = 3.0f; // Thickkness of border in SeparatorText() + SeparatorTextAlign = ImVec2(0.0f,0.5f);// Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). + SeparatorTextPadding = ImVec2(20.0f,3.f);// Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. + DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. + DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. + AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). + AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.). + CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + CircleTessellationMaxError = 0.30f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry. // Behaviors - HoverStationaryDelay = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary. - HoverDelayShort = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay. - HoverDelayNormal = 0.40f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). " - HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse. - HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad. + HoverStationaryDelay = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_Stationary). Time required to consider mouse stationary. + HoverDelayShort = 0.15f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayShort). Usually used along with HoverStationaryDelay. + HoverDelayNormal = 0.40f; // Delay for IsItemHovered(ImGuiHoveredFlags_DelayNormal). " + HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse. + HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad. // Default theme ImGui::StyleColorsDark(this); @@ -1464,7 +1508,7 @@ static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventT // - bool down: Is the key down? use false to signify a key release. // - float analog_value: 0.0f..1.0f // IMPORTANT: THIS FUNCTION AND OTHER "ADD" GRABS THE CONTEXT FROM OUR INSTANCE. -// WE NEED TO ENSURE THAT ALL FUNCTION CALLS ARE FULLFILLING THIS, WHICH IS WHY GetKeyData() HAS AN EXPLICIT CONTEXT. +// WE NEED TO ENSURE THAT ALL FUNCTION CALLS ARE FULFILLING THIS, WHICH IS WHY GetKeyData() HAS AN EXPLICIT CONTEXT. void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value) { //if (e->Down) { IMGUI_DEBUG_LOG_IO("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); } @@ -1472,9 +1516,19 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value) if (key == ImGuiKey_None || !AppAcceptingEvents) return; ImGuiContext& g = *Ctx; - IM_ASSERT(ImGui::IsNamedKeyOrModKey(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API. + IM_ASSERT(ImGui::IsNamedKeyOrMod(key)); // Backend needs to pass a valid ImGuiKey_ constant. 0..511 values are legacy native key codes which are not accepted by this API. IM_ASSERT(ImGui::IsAliasKey(key) == false); // Backend cannot submit ImGuiKey_MouseXXX values they are automatically inferred from AddMouseXXX() events. - IM_ASSERT(key != ImGuiMod_Shortcut); // We could easily support the translation here but it seems saner to not accept it (TestEngine perform a translation itself) + + // MacOS: swap Cmd(Super) and Ctrl + if (g.IO.ConfigMacOSXBehaviors) + { + if (key == ImGuiMod_Super) { key = ImGuiMod_Ctrl; } + else if (key == ImGuiMod_Ctrl) { key = ImGuiMod_Super; } + else if (key == ImGuiKey_LeftSuper) { key = ImGuiKey_LeftCtrl; } + else if (key == ImGuiKey_RightSuper){ key = ImGuiKey_RightCtrl; } + else if (key == ImGuiKey_LeftCtrl) { key = ImGuiKey_LeftSuper; } + else if (key == ImGuiKey_RightCtrl) { key = ImGuiKey_RightSuper; } + } // Verify that backend isn't mixing up using new io.AddKeyEvent() api and old io.KeysDown[] + io.KeyMap[] data. #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO @@ -1579,12 +1633,36 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down) if (!AppAcceptingEvents) return; + // On MacOS X: Convert Ctrl(Super)+Left click into Right-click: handle held button. + if (ConfigMacOSXBehaviors && mouse_button == 0 && MouseCtrlLeftAsRightClick) + { + // Order of both statements matterns: this event will still release mouse button 1 + mouse_button = 1; + if (!down) + MouseCtrlLeftAsRightClick = false; + } + // Filter duplicate const ImGuiInputEvent* latest_event = FindLatestInputEvent(&g, ImGuiInputEventType_MouseButton, (int)mouse_button); const bool latest_button_down = latest_event ? latest_event->MouseButton.Down : g.IO.MouseDown[mouse_button]; if (latest_button_down == down) return; + // On MacOS X: Convert Ctrl(Super)+Left click into Right-click. + // - Note that this is actual physical Ctrl which is ImGuiMod_Super for us. + // - At this point we want from !down to down, so this is handling the initial press. + if (ConfigMacOSXBehaviors && mouse_button == 0 && down) + { + const ImGuiInputEvent* latest_super_event = FindLatestInputEvent(&g, ImGuiInputEventType_Key, (int)ImGuiMod_Super); + if (latest_super_event ? latest_super_event->Key.Down : g.IO.KeySuper) + { + IMGUI_DEBUG_LOG_IO("[io] Super+Left Click aliased into Right Click\n"); + MouseCtrlLeftAsRightClick = true; + AddMouseButtonEvent(1, true); // This is just quicker to write that passing through, as we need to filter duplicate again. + return; + } + } + ImGuiInputEvent e; e.Type = ImGuiInputEventType_MouseButton; e.Source = ImGuiInputSource_Mouse; @@ -2320,6 +2398,20 @@ const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const cha return in_text_start; } +int ImTextCountLines(const char* in_text, const char* in_text_end) +{ + if (in_text_end == NULL) + in_text_end = in_text + strlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now. + int count = 0; + while (in_text < in_text_end) + { + const char* line_end = (const char*)memchr(in_text, '\n', in_text_end - in_text); + in_text = line_end ? line_end + 1 : in_text_end; + count++; + } + return count; +} + IM_MSVC_RUNTIME_CHECKS_RESTORE //----------------------------------------------------------------------------- @@ -2413,18 +2505,16 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& //----------------------------------------------------------------------------- // std::lower_bound but without the bullshit -static ImGuiStorage::ImGuiStoragePair* LowerBound(ImVector& data, ImGuiID key) +ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key) { - ImGuiStorage::ImGuiStoragePair* first = data.Data; - ImGuiStorage::ImGuiStoragePair* last = data.Data + data.Size; - size_t count = (size_t)(last - first); - while (count > 0) + ImGuiStoragePair* in_p = in_begin; + for (size_t count = (size_t)(in_end - in_p); count > 0; ) { size_t count2 = count >> 1; - ImGuiStorage::ImGuiStoragePair* mid = first + count2; + ImGuiStoragePair* mid = in_p + count2; if (mid->key < key) { - first = ++mid; + in_p = ++mid; count -= count2 + 1; } else @@ -2432,7 +2522,7 @@ static ImGuiStorage::ImGuiStoragePair* LowerBound(ImVector&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return default_val; return it->val_i; @@ -2466,7 +2556,7 @@ bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { - ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return default_val; return it->val_f; @@ -2474,7 +2564,7 @@ float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const void* ImGuiStorage::GetVoidPtr(ImGuiID key) const { - ImGuiStoragePair* it = LowerBound(const_cast&>(Data), key); + ImGuiStoragePair* it = ImLowerBound(const_cast(Data.Data), const_cast(Data.Data + Data.Size), key); if (it == Data.end() || it->key != key) return NULL; return it->val_p; @@ -2483,7 +2573,7 @@ void* ImGuiStorage::GetVoidPtr(ImGuiID key) const // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_i; @@ -2496,7 +2586,7 @@ bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_f; @@ -2504,7 +2594,7 @@ float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) it = Data.insert(it, ImGuiStoragePair(key, default_val)); return &it->val_p; @@ -2513,7 +2603,7 @@ void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) void ImGuiStorage::SetInt(ImGuiID key, int val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -2527,7 +2617,7 @@ void ImGuiStorage::SetBool(ImGuiID key, bool val) void ImGuiStorage::SetFloat(ImGuiID key, float val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -2536,7 +2626,7 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val) void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { - ImGuiStoragePair* it = LowerBound(Data, key); + ImGuiStoragePair* it = ImLowerBound(Data.Data, Data.Data + Data.Size, key); if (it == Data.end() || it->key != key) Data.insert(it, ImGuiStoragePair(key, val)); else @@ -3102,35 +3192,38 @@ void ImGui::PopStyleColor(int count) static const ImGuiDataVarInfo GStyleVarInfo[] = { - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign - { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)},// ImGuiStyleVar_SeparatorTextBorderSize - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign - { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign + { ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign + { ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding }; const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx) @@ -3774,50 +3867,12 @@ ImGuiWindow::~ImGuiWindow() ColumnsStorage.clear_destruct(); } -ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); - ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); - return id; -} - -ImGuiID ImGuiWindow::GetID(const void* ptr) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); - ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); - return id; -} - -ImGuiID ImGuiWindow::GetID(int n) -{ - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHashData(&n, sizeof(n), seed); - ImGuiContext& g = *Ctx; - if (g.DebugHookIdInfo == id) - ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); - return id; -} - -// This is only used in rare/specific situations to manufacture an ID out of nowhere. -ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) -{ - ImGuiID seed = IDStack.back(); - ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs); - ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed); - return id; -} - static void SetCurrentWindow(ImGuiWindow* window) { ImGuiContext& g = *GImGui; g.CurrentWindow = window; g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL; + g.CurrentDpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking if (window) { g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); @@ -4118,7 +4173,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag // Done with rectangle culling so we can perform heavier checks now. if (!(item_flags & ImGuiItemFlags_NoWindowHoverableCheck) && !IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) { - g.HoveredIdDisabled = true; + g.HoveredIdIsDisabled = true; return false; } @@ -4140,6 +4195,11 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag if (g.HoveredIdPreviousFrame != id) return false; } + + // Display shortcut (only works with mouse) + if (id == g.LastItemData.ID && (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasShortcut)) + if (IsItemHovered(ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_DelayNormal)) + SetTooltip("%s", GetKeyChordName(g.LastItemData.Shortcut)); } // When disabled we'll return false but still set HoveredId @@ -4148,7 +4208,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag // Release active id if turning disabled if (g.ActiveId == id && id != 0) ClearActiveID(); - g.HoveredIdDisabled = true; + g.HoveredIdIsDisabled = true; return false; } @@ -4180,7 +4240,7 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id) ImGuiWindow* window = g.CurrentWindow; if (!bb.Overlaps(window->ClipRect)) if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId)) - if (!g.LogEnabled) + if (!g.ItemUnclipByLog) return true; return false; } @@ -4451,7 +4511,7 @@ void ImGui::UpdateMouseMovingWindowEndFrame() g.MovingWindow = NULL; // Cancel moving if clicked over an item which was disabled or inhibited by popups (note that we know HoveredId == 0 already) - if (g.HoveredIdDisabled) + if (g.HoveredIdIsDisabled) g.MovingWindow = NULL; } else if (root_window == NULL && g.NavWindow != NULL) @@ -4484,6 +4544,9 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() { ImGuiContext& g = *GImGui; ImGuiIO& io = g.IO; + + // FIXME-DPI: This storage was added on 2021/03/31 for test engine, but if we want to multiply WINDOWS_HOVER_PADDING + // by DpiScale, we need to make this window-agnostic anyhow, maybe need storing inside ImGuiWindow. g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING)); // Find the window hovered by mouse: @@ -4491,7 +4554,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame. // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. bool clear_hovered_windows = false; - FindHoveredWindow(); + FindHoveredWindowEx(g.IO.MousePos, false, &g.HoveredWindow, &g.HoveredWindowUnderMovingWindow); // Modal windows prevents mouse from hovering behind them. ImGuiWindow* modal_window = GetTopMostPopupModal(); @@ -4555,6 +4618,27 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() io.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; } +// Calling SetupDrawListSharedData() is followed by SetCurrentFont() which sets up the remaining data. +static void SetupDrawListSharedData() +{ + ImGuiContext& g = *GImGui; + ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); + for (ImGuiViewportP* viewport : g.Viewports) + virtual_space.Add(viewport->GetMainRect()); + g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4(); + g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; + g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError); + g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; + if (g.Style.AntiAliasedLines) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines; + if (g.Style.AntiAliasedLinesUseTex && !(g.IO.Fonts->Flags & ImFontAtlasFlags_NoBakedLines)) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex; + if (g.Style.AntiAliasedFill) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; + if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) + g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; +} + void ImGui::NewFrame() { IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?"); @@ -4597,23 +4681,9 @@ void ImGui::NewFrame() // Setup current font and draw list shared data g.IO.Fonts->Locked = true; + SetupDrawListSharedData(); SetCurrentFont(GetDefaultFont()); IM_ASSERT(g.Font->IsLoaded()); - ImRect virtual_space(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); - for (ImGuiViewportP* viewport : g.Viewports) - virtual_space.Add(viewport->GetMainRect()); - g.DrawListSharedData.ClipRectFullscreen = virtual_space.ToVec4(); - g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; - g.DrawListSharedData.SetCircleTessellationMaxError(g.Style.CircleTessellationMaxError); - g.DrawListSharedData.InitialFlags = ImDrawListFlags_None; - if (g.Style.AntiAliasedLines) - g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines; - if (g.Style.AntiAliasedLinesUseTex && !(g.Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines)) - g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLinesUseTex; - if (g.Style.AntiAliasedFill) - g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill; - if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) - g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset; // Mark rendering data as invalid to prevent user who may have a handle on it to use it. for (ImGuiViewportP* viewport : g.Viewports) @@ -4635,7 +4705,7 @@ void ImGui::NewFrame() g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredId = 0; g.HoveredIdAllowOverlap = false; - g.HoveredIdDisabled = false; + g.HoveredIdIsDisabled = false; // Clear ActiveID if the item is not alive anymore. // In 1.87, the common most call to KeepAliveID() was moved from GetID() to ItemAdd(). @@ -5211,16 +5281,18 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex } // Find window given position, search front-to-back -// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically -// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is -// called, aka before the next Begin(). Moving window isn't affected. -static void FindHoveredWindow() +// - Typically write output back to g.HoveredWindow and g.HoveredWindowUnderMovingWindow. +// - FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically +// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is +// called, aka before the next Begin(). Moving window isn't affected. +// - The 'find_first_and_in_any_viewport = true' mode is only used by TestEngine. It is simpler to maintain here. +void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window) { ImGuiContext& g = *GImGui; - ImGuiWindow* hovered_window = NULL; - ImGuiWindow* hovered_window_ignoring_moving_window = NULL; - if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) + ImGuiWindow* hovered_window_under_moving_window = NULL; + + if (find_first_and_in_any_viewport == false && g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) hovered_window = g.MovingWindow; ImVec2 padding_regular = g.Style.TouchExtraPadding; @@ -5236,7 +5308,7 @@ static void FindHoveredWindow() // Using the clipped AABB, a child window will typically be clipped by its parent (not always) ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize; - if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding)) + if (!window->OuterRectClipped.ContainsWithPad(pos, hit_padding)) continue; // Support for one rectangular hole in any given window @@ -5245,21 +5317,30 @@ static void FindHoveredWindow() { ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y); ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y); - if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos)) + if (ImRect(hole_pos, hole_pos + hole_size).Contains(pos)) continue; } - if (hovered_window == NULL) + if (find_first_and_in_any_viewport) + { hovered_window = window; - IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. - if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow)) - hovered_window_ignoring_moving_window = window; - if (hovered_window && hovered_window_ignoring_moving_window) break; + } + else + { + if (hovered_window == NULL) + hovered_window = window; + IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. + if (hovered_window_under_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow)) + hovered_window_under_moving_window = window; + if (hovered_window && hovered_window_under_moving_window) + break; + } } - g.HoveredWindow = hovered_window; - g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; + *out_hovered_window = hovered_window; + if (out_hovered_window_under_moving_window != NULL) + *out_hovered_window_under_moving_window = hovered_window_under_moving_window; } bool ImGui::IsItemActive() @@ -5559,7 +5640,9 @@ void ImGui::EndChild() else { // Not navigable into - ItemAdd(bb, 0); + // - This is a bit of a fringe use case, mostly useful for undecorated, non-scrolling contents childs, or empty childs. + // - We could later decide to not apply this path if ImGuiChildFlags_FrameStyle or ImGuiChildFlags_Borders is set. + ItemAdd(bb, child_window->ChildId, NULL, ImGuiItemFlags_NoNav); // But when flattened we directly reach items, adjust active layer mask accordingly if (child_window->Flags & ImGuiWindowFlags_NavFlattened) @@ -5697,7 +5780,7 @@ static inline ImVec2 CalcWindowMinSize(ImGuiWindow* window) // Reduce artifacts with very small windows ImGuiWindow* window_for_height = window; - size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); + size_min.y = ImMax(size_min.y, window_for_height->TitleBarHeight + window_for_height->MenuBarHeight + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); return size_min; } @@ -5770,10 +5853,18 @@ static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_cont ImVec2 size_max = ((window->Flags & ImGuiWindowFlags_ChildWindow) && !(window->Flags & ImGuiWindowFlags_Popup)) ? ImVec2(FLT_MAX, FLT_MAX) : ImGui::GetMainViewport()->WorkSize - style.DisplaySafeAreaPadding * 2.0f; ImVec2 size_auto_fit = ImClamp(size_desired, size_min, size_max); + // FIXME: CalcWindowAutoFitSize() doesn't take into account that only one axis may be auto-fit when calculating scrollbars, + // we may need to compute/store three variants of size_auto_fit, for x/y/xy. + // Here we implement a workaround for child windows only, but a full solution would apply to normal windows as well: + if ((window->ChildFlags & ImGuiChildFlags_ResizeX) && !(window->ChildFlags & ImGuiChildFlags_ResizeY)) + size_auto_fit.y = window->SizeFull.y; + else if (!(window->ChildFlags & ImGuiChildFlags_ResizeX) && (window->ChildFlags & ImGuiChildFlags_ResizeY)) + size_auto_fit.x = window->SizeFull.x; + // When the window cannot fit all contents (either because of constraints, either because screen is too small), // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit); - bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - decoration_w_without_scrollbars < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); + bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - decoration_w_without_scrollbars < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar); bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - decoration_h_without_scrollbars < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar); if (will_have_scrollbar_x) size_auto_fit.y += style.ScrollbarSize; @@ -5894,13 +5985,13 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si int ret_auto_fit_mask = 0x00; const float grip_draw_size = IM_TRUNC(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f)); - const float grip_hover_inner_size = IM_TRUNC(grip_draw_size * 0.75f); + const float grip_hover_inner_size = (resize_grip_count > 0) ? IM_TRUNC(grip_draw_size * 0.75f) : 0.0f; const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_HOVER_PADDING : 0.0f; ImRect clamp_rect = visibility_rect; const bool window_move_from_title_bar = g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar); if (window_move_from_title_bar) - clamp_rect.Min.y -= window->TitleBarHeight(); + clamp_rect.Min.y -= window->TitleBarHeight; ImVec2 pos_target(FLT_MAX, FLT_MAX); ImVec2 size_target(FLT_MAX, FLT_MAX); @@ -5975,6 +6066,7 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si if (held && g.IO.MouseDoubleClicked[0]) { // Double-clicking bottom or right border auto-fit on this axis + // FIXME: CalcWindowAutoFitSize() doesn't take into account that only one side may be auto-fit when calculating scrollbars. // FIXME: Support top and right borders: rework CalcResizePosSizeFromAnyCorner() to be reusable in both cases. if (border_n == 1 || border_n == 3) // Right and bottom border { @@ -6022,10 +6114,13 @@ static int ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& si border_target = ImClamp(border_target, clamp_min, clamp_max); if (flags & ImGuiWindowFlags_ChildWindow) // Clamp resizing of childs within parent { - if ((flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (flags & ImGuiWindowFlags_NoScrollbar)) - border_target.x = ImClamp(border_target.x, window->ParentWindow->InnerClipRect.Min.x, window->ParentWindow->InnerClipRect.Max.x); - if (flags & ImGuiWindowFlags_NoScrollbar) - border_target.y = ImClamp(border_target.y, window->ParentWindow->InnerClipRect.Min.y, window->ParentWindow->InnerClipRect.Max.y); + ImGuiWindowFlags parent_flags = window->ParentWindow->Flags; + ImRect border_limit_rect = window->ParentWindow->InnerRect; + border_limit_rect.Expand(ImVec2(-ImMax(window->WindowPadding.x, window->WindowBorderSize), -ImMax(window->WindowPadding.y, window->WindowBorderSize))); + if ((parent_flags & (ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar)) == 0 || (parent_flags & ImGuiWindowFlags_NoScrollbar)) + border_target.x = ImClamp(border_target.x, border_limit_rect.Min.x, border_limit_rect.Max.x); + if (parent_flags & ImGuiWindowFlags_NoScrollbar) + border_target.y = ImClamp(border_target.y, border_limit_rect.Min.y, border_limit_rect.Max.y); } if (!ignore_resize) CalcResizePosSizeFromAnyCorner(window, border_target, ImMin(def.SegmentN1, def.SegmentN2), &pos_target, &size_target); @@ -6095,7 +6190,7 @@ static inline void ClampWindowPos(ImGuiWindow* window, const ImRect& visibility_ ImGuiContext& g = *GImGui; ImVec2 size_for_clamping = window->Size; if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) - size_for_clamping.y = window->TitleBarHeight(); + size_for_clamping.y = window->TitleBarHeight; window->Pos = ImClamp(window->Pos, visibility_rect.Min - size_for_clamping, visibility_rect.Max); } @@ -6131,7 +6226,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) } if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) { - float y = window->Pos.y + window->TitleBarHeight() - 1; + float y = window->Pos.y + window->TitleBarHeight - 1; window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), border_col, g.Style.FrameBorderSize); } } @@ -6176,7 +6271,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar } if (override_alpha) bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT); - window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom); + window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? 0 : ImDrawFlags_RoundCornersBottom); } // Title bar @@ -6331,6 +6426,30 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags } } +// [EXPERIMENTAL] Called by Begin(). NextWindowData is valid at this point. +// This is designed as a toy/test-bed for +void ImGui::UpdateWindowSkipRefresh(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + window->SkipRefresh = false; + if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasRefreshPolicy) == 0) + return; + if (g.NextWindowData.RefreshFlagsVal & ImGuiWindowRefreshFlags_TryToAvoidRefresh) + { + // FIXME-IDLE: Tests for e.g. mouse clicks or keyboard while focused. + if (window->Appearing) // If currently appearing + return; + if (window->Hidden) // If was hidden (previous frame) + return; + if ((g.NextWindowData.RefreshFlagsVal & ImGuiWindowRefreshFlags_RefreshOnHover) && g.HoveredWindow && window->RootWindow == g.HoveredWindow->RootWindow) + return; + if ((g.NextWindowData.RefreshFlagsVal & ImGuiWindowRefreshFlags_RefreshOnFocus) && g.NavWindow && window->RootWindow == g.NavWindow->RootWindow) + return; + window->DrawList = NULL; + window->SkipRefresh = true; + } +} + // When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) // should be positioned behind that modal window, unless the window was created inside the modal begin-stack. // In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. @@ -6343,7 +6462,7 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags // - WindowE // .. returns NULL // Notes: // - FindBlockingModal(NULL) == NULL is generally equivalent to GetTopMostPopupModal() == NULL. -// Only difference is here we check for ->Active/WasActive but it may be unecessary. +// Only difference is here we check for ->Active/WasActive but it may be unnecessary. ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -6446,6 +6565,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window_stack_data.Window = window; window_stack_data.ParentLastItemDataBackup = g.LastItemData; window_stack_data.StackSizesOnBegin.SetToContextState(&g); + window_stack_data.DisabledOverrideReenable = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0; g.CurrentWindowStack.push_back(window_stack_data); if (flags & ImGuiWindowFlags_ChildMenu) g.BeginMenuDepth++; @@ -6465,7 +6585,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) PushFocusScope((flags & ImGuiWindowFlags_NavFlattened) ? g.CurrentFocusScopeId : window->ID); window->NavRootFocusScopeId = g.CurrentFocusScopeId; - // Add to popup stack + // Add to popup stacks: update OpenPopupStack[] data, push to BeginPopupStack[] if (flags & ImGuiWindowFlags_Popup) { ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size]; @@ -6529,11 +6649,18 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); + // [EXPERIMENTAL] Skip Refresh mode + UpdateWindowSkipRefresh(window); + + // Nested root windows (typically tooltips) override disabled state + if (window_stack_data.DisabledOverrideReenable && window->RootWindow == window) + BeginDisabledOverrideReenable(); + // We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow() g.CurrentWindow = NULL; // When reusing window again multiple times a frame, just append content (don't need to setup again) - if (first_begin_of_the_frame) + if (first_begin_of_the_frame && !window->SkipRefresh) { // Initialize const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) @@ -6611,9 +6738,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Lock menu offset so size calculation can use it as menu-bar windows need a minimum size. window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x); window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y; + window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f; + window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f; + // Depending on condition we use previous or current window size to compare against contents size to decide if a scrollbar should be visible. + // Those flags will be altered further down in the function depending on more conditions. bool use_current_size_for_scrollbar_x = window_just_created; bool use_current_size_for_scrollbar_y = window_just_created; + if (window_size_x_set_by_api && window->ContentSizeExplicit.x != 0.0f) + use_current_size_for_scrollbar_x = true; + if (window_size_y_set_by_api && window->ContentSizeExplicit.y != 0.0f) // #7252 + use_current_size_for_scrollbar_y = true; // Collapse window by double-clicking on title bar // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing @@ -6621,8 +6756,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar. ImRect title_bar_rect = window->TitleBarRect(); - if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseClickedCount[0] == 2) - window->WantCollapseToggle = true; + if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max)) + if (g.IO.MouseClickedCount[0] == 2 && GetKeyOwner(ImGuiKey_MouseLeft) == ImGuiKeyOwner_NoOwner) + window->WantCollapseToggle = true; if (window->WantCollapseToggle) { window->Collapsed = !window->Collapsed; @@ -6640,11 +6776,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE // Outer Decoration Sizes - // (we need to clear ScrollbarSize immediatly as CalcWindowAutoFitSize() needs it and can be called from other locations). + // (we need to clear ScrollbarSize immediately as CalcWindowAutoFitSize() needs it and can be called from other locations). const ImVec2 scrollbar_sizes_from_last_frame = window->ScrollbarSizes; window->DecoOuterSizeX1 = 0.0f; window->DecoOuterSizeX2 = 0.0f; - window->DecoOuterSizeY1 = window->TitleBarHeight() + window->MenuBarHeight(); + window->DecoOuterSizeY1 = window->TitleBarHeight + window->MenuBarHeight; window->DecoOuterSizeY2 = 0.0f; window->ScrollbarSizes = ImVec2(0.0f, 0.0f); @@ -6793,7 +6929,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); // Amend the partially filled window->DecorationXXX values. @@ -6828,17 +6964,19 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->DecoOuterSizeY2; // Inner clipping rectangle. - // Will extend a little bit outside the normal work region. - // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space. - // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + // - Extend a outside of normal work region up to borders. + // - This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space. + // - It also makes clipped items be more noticeable. + // - And is consistent on both axis (prior to 2024/05/03 ClipRect used WindowPadding.x * 0.5f on left and right edge), see #3312 + // - Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior. // Affected by window/frame border size. Used by: // - Begin() initial clip rect float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); - window->InnerClipRect.Min.x = ImTrunc(0.5f + window->InnerRect.Min.x + ImMax(ImTrunc(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); - window->InnerClipRect.Min.y = ImTrunc(0.5f + window->InnerRect.Min.y + top_border_size); - window->InnerClipRect.Max.x = ImTrunc(0.5f + window->InnerRect.Max.x - ImMax(ImTrunc(window->WindowPadding.x * 0.5f), window->WindowBorderSize)); - window->InnerClipRect.Max.y = ImTrunc(0.5f + window->InnerRect.Max.y - window->WindowBorderSize); + window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + window->WindowBorderSize); + window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size); + window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - window->WindowBorderSize); + window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize); window->InnerClipRect.ClipWithFull(host_rect); // Default item width. Make it proportional to window size if window manually resizes @@ -6999,7 +7137,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). // This is useful to allow creating context menus on title bar only, etc. - SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect); + SetLastItemDataForWindow(window, title_bar_rect); // [DEBUG] #ifndef IMGUI_DISABLE_DEBUG_TOOLS @@ -7015,11 +7153,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } else { + // Skip refresh always mark active + if (window->SkipRefresh) + window->Active = true; + // Append SetCurrentWindow(window); + SetLastItemDataForWindow(window, window->TitleBarRect()); } - PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); + if (!window->SkipRefresh) + PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) window->WriteAccessed = false; @@ -7027,7 +7171,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) g.NextWindowData.ClearFlags(); // Update visibility - if (first_begin_of_the_frame) + if (first_begin_of_the_frame && !window->SkipRefresh) { if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ChildMenu)) { @@ -7073,6 +7217,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) skip_items = true; window->SkipItems = skip_items; } + else if (first_begin_of_the_frame) + { + // Skip refresh mode + window->SkipItems = true; + } // [DEBUG] io.ConfigDebugBeginReturnValue override return value to test Begin/End and BeginChild/EndChild behaviors. // (The implicit fallback window is NOT automatically ended allowing it to always be able to receive commands without crashing) @@ -7089,6 +7238,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) return !window->SkipItems; } +static void ImGui::SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect) +{ + ImGuiContext& g = *GImGui; + SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(rect.Min, rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, rect); +} + void ImGui::End() { ImGuiContext& g = *GImGui; @@ -7100,7 +7255,7 @@ void ImGui::End() IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size > 1, "Calling End() too many times!"); return; } - IM_ASSERT(g.CurrentWindowStack.Size > 0); + ImGuiWindowStackData& window_stack_data = g.CurrentWindowStack.back(); // Error checking: verify that user doesn't directly call End() on a child window. if (window->Flags & ImGuiWindowFlags_ChildWindow) @@ -7109,8 +7264,17 @@ void ImGui::End() // Close anything that is open if (window->DC.CurrentColumns) EndColumns(); - PopClipRect(); // Inner window clip rectangle + if (!window->SkipRefresh) + PopClipRect(); // Inner window clip rectangle PopFocusScope(); + if (window_stack_data.DisabledOverrideReenable && window->RootWindow == window) + EndDisabledOverrideReenable(); + + if (window->SkipRefresh) + { + IM_ASSERT(window->DrawList == NULL); + window->DrawList = &window->DrawListInst; + } // Stop logging if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging @@ -7120,12 +7284,12 @@ void ImGui::End() ErrorCheckUsingSetCursorPosToExtendParentBoundaries(); // Pop from window stack - g.LastItemData = g.CurrentWindowStack.back().ParentLastItemDataBackup; + g.LastItemData = window_stack_data.ParentLastItemDataBackup; if (window->Flags & ImGuiWindowFlags_ChildMenu) g.BeginMenuDepth--; if (window->Flags & ImGuiWindowFlags_Popup) g.BeginPopupStack.pop_back(); - g.CurrentWindowStack.back().StackSizesOnBegin.CompareWithContextState(&g); + window_stack_data.StackSizesOnBegin.CompareWithContextState(&g); g.CurrentWindowStack.pop_back(); SetCurrentWindow(g.CurrentWindowStack.Size == 0 ? NULL : g.CurrentWindowStack.back().Window); } @@ -7217,9 +7381,13 @@ void ImGui::FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags) if ((flags & ImGuiFocusRequestFlags_UnlessBelowModal) && (g.NavWindow != window)) // Early out in common case. if (ImGuiWindow* blocking_modal = FindBlockingModal(window)) { + // This block would typically be reached in two situations: + // - API call to FocusWindow() with a window under a modal and ImGuiFocusRequestFlags_UnlessBelowModal flag. + // - User clicking on void or anything behind a modal while a modal is open (window == NULL) IMGUI_DEBUG_LOG_FOCUS("[focus] FocusWindow(\"%s\", UnlessBelowModal): prevented by \"%s\".\n", window ? window->Name : "", blocking_modal->Name); if (window && window == window->RootWindow && (window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0) - BringWindowToDisplayBehind(window, blocking_modal); // Still bring to right below modal. + BringWindowToDisplayBehind(window, blocking_modal); // Still bring right under modal. (FIXME: Could move in focus list too?) + ClosePopupsOverWindow(GetTopMostPopupModal(), false); // Note how we need to use GetTopMostPopupModal() aad NOT blocking_modal, to handle nested modals return; } @@ -7369,7 +7537,7 @@ void ImGui::BeginDisabled(bool disabled) } if (was_disabled || disabled) g.CurrentItemFlags |= ImGuiItemFlags_Disabled; - g.ItemFlagsStack.push_back(g.CurrentItemFlags); + g.ItemFlagsStack.push_back(g.CurrentItemFlags); // FIXME-OPT: can we simply skip this and use DisabledStackSize? g.DisabledStackSize++; } @@ -7386,6 +7554,29 @@ void ImGui::EndDisabled() g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); } +// Could have been called BeginDisabledDisable() but it didn't want to be award nominated for most awkward function name. +// Ideally we would use a shared e.g. BeginDisabled()->BeginDisabledEx() but earlier needs to be optimal. +// The whole code for this is awkward, will reevaluate if we find a way to implement SetNextItemDisabled(). +void ImGui::BeginDisabledOverrideReenable() +{ + ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentItemFlags & ImGuiItemFlags_Disabled); + g.Style.Alpha = g.DisabledAlphaBackup; + g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled; + g.ItemFlagsStack.push_back(g.CurrentItemFlags); + g.DisabledStackSize++; +} + +void ImGui::EndDisabledOverrideReenable() +{ + ImGuiContext& g = *GImGui; + g.DisabledStackSize--; + IM_ASSERT(g.DisabledStackSize > 0); + g.ItemFlagsStack.pop_back(); + g.CurrentItemFlags = g.ItemFlagsStack.back(); + g.Style.Alpha = g.DisabledAlphaBackup * g.Style.DisabledAlpha; +} + void ImGui::PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); @@ -7520,7 +7711,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) // When changing hovered window we requires a bit of stationary delay before activating hover timer. // FIXME: We don't support delay other than stationary one for now, other delay would need a way - // to fullfill the possibility that multiple IsWindowHovered() with varying flag could return true + // to fulfill the possibility that multiple IsWindowHovered() with varying flag could return true // for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache. // We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow. if (flags & ImGuiHoveredFlags_ForTooltip) @@ -7796,6 +7987,14 @@ void ImGui::SetNextWindowBgAlpha(float alpha) g.NextWindowData.BgAlphaVal = alpha; } +// This is experimental and meant to be a toy for exploring a future/wider range of features. +void ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags) +{ + ImGuiContext& g = *GImGui; + g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasRefreshPolicy; + g.NextWindowData.RefreshFlagsVal = flags; +} + ImDrawList* ImGui::GetWindowDrawList() { ImGuiWindow* window = GetCurrentWindow(); @@ -7966,6 +8165,69 @@ ImGuiStorage* ImGui::GetStateStorage() return window->DC.StateStorage; } +bool ImGui::IsRectVisible(const ImVec2& size) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); +} + +bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) +{ + ImGuiWindow* window = GImGui->CurrentWindow; + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); +} + +//----------------------------------------------------------------------------- +// [SECTION] ID STACK +//----------------------------------------------------------------------------- + +// This is one of the very rare legacy case where we use ImGuiWindow methods, +// it should ideally be flattened at some point but it's been used a lots by widgets. +ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + ImGuiContext& g = *Ctx; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); +#endif + return id; +} + +ImGuiID ImGuiWindow::GetID(const void* ptr) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&ptr, sizeof(void*), seed); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + ImGuiContext& g = *Ctx; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_Pointer, ptr, NULL); +#endif + return id; +} + +ImGuiID ImGuiWindow::GetID(int n) +{ + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHashData(&n, sizeof(n), seed); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS + ImGuiContext& g = *Ctx; + if (g.DebugHookIdInfo == id) + ImGui::DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); +#endif + return id; +} + +// This is only used in rare/specific situations to manufacture an ID out of nowhere. +ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) +{ + ImGuiID seed = IDStack.back(); + ImRect r_rel = ImGui::WindowRectAbsToRel(this, r_abs); + ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed); + return id; +} + void ImGui::PushID(const char* str_id) { ImGuiContext& g = *GImGui; @@ -8003,8 +8265,10 @@ void ImGui::PushOverrideID(ImGuiID id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; +#ifndef IMGUI_DISABLE_DEBUG_TOOLS if (g.DebugHookIdInfo == id) DebugHookIdInfo(id, ImGuiDataType_ID, NULL, NULL); +#endif window->IDStack.push_back(id); } @@ -8014,18 +8278,22 @@ void ImGui::PushOverrideID(ImGuiID id) ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed) { ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *GImGui; if (g.DebugHookIdInfo == id) DebugHookIdInfo(id, ImGuiDataType_String, str, str_end); +#endif return id; } ImGuiID ImGui::GetIDWithSeed(int n, ImGuiID seed) { ImGuiID id = ImHashData(&n, sizeof(n), seed); +#ifndef IMGUI_DISABLE_DEBUG_TOOLS ImGuiContext& g = *GImGui; if (g.DebugHookIdInfo == id) DebugHookIdInfo(id, ImGuiDataType_S32, (void*)(intptr_t)n, NULL); +#endif return id; } @@ -8054,22 +8322,11 @@ ImGuiID ImGui::GetID(const void* ptr_id) return window->GetID(ptr_id); } -bool ImGui::IsRectVisible(const ImVec2& size) -{ - ImGuiWindow* window = GImGui->CurrentWindow; - return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); -} - -bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) -{ - ImGuiWindow* window = GImGui->CurrentWindow; - return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); -} - - //----------------------------------------------------------------------------- // [SECTION] INPUTS //----------------------------------------------------------------------------- +// - GetModForModKey() [Internal] +// - FixupKeyChord() [Internal] // - GetKeyData() [Internal] // - GetKeyIndex() [Internal] // - GetKeyName() @@ -8131,23 +8388,25 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) // - Shortcut() [Internal] //----------------------------------------------------------------------------- -ImGuiKeyChord ImGui::FixupKeyChord(ImGuiContext* ctx, ImGuiKeyChord key_chord) +static ImGuiKeyChord GetModForModKey(ImGuiKey key) +{ + if (key == ImGuiKey_LeftCtrl || key == ImGuiKey_RightCtrl) + return ImGuiMod_Ctrl; + if (key == ImGuiKey_LeftShift || key == ImGuiKey_RightShift) + return ImGuiMod_Shift; + if (key == ImGuiKey_LeftAlt || key == ImGuiKey_RightAlt) + return ImGuiMod_Alt; + if (key == ImGuiKey_LeftSuper || key == ImGuiKey_RightSuper) + return ImGuiMod_Super; + return ImGuiMod_None; +} + +ImGuiKeyChord ImGui::FixupKeyChord(ImGuiKeyChord key_chord) { - // Convert ImGuiMod_Shortcut and add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. + // Add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); if (IsModKey(key)) - { - if (key == ImGuiKey_LeftCtrl || key == ImGuiKey_RightCtrl) - key_chord |= ImGuiMod_Ctrl; - if (key == ImGuiKey_LeftShift || key == ImGuiKey_RightShift) - key_chord |= ImGuiMod_Shift; - if (key == ImGuiKey_LeftAlt || key == ImGuiKey_RightAlt) - key_chord |= ImGuiMod_Alt; - if (key == ImGuiKey_LeftSuper || key == ImGuiKey_RightSuper) - key_chord |= ImGuiMod_Super; - } - if (key_chord & ImGuiMod_Shortcut) - return (key_chord & ~ImGuiMod_Shortcut) | (ctx->IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); + key_chord |= GetModForModKey(key); return key_chord; } @@ -8157,7 +8416,7 @@ ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key) // Special storage location for mods if (key & ImGuiMod_Mask_) - key = ConvertSingleModFlagToKey(ctx, key); + key = ConvertSingleModFlagToKey(key); #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO IM_ASSERT(key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_NamedKey_END); @@ -8170,6 +8429,7 @@ ImGuiKeyData* ImGui::GetKeyData(ImGuiContext* ctx, ImGuiKey key) } #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO +// Formally moved to obsolete section in 1.90.5 in spite of documented as obsolete since 1.87 ImGuiKey ImGui::GetKeyIndex(ImGuiKey key) { ImGuiContext& g = *GImGui; @@ -8208,10 +8468,12 @@ IM_STATIC_ASSERT(ImGuiKey_NamedKey_COUNT == IM_ARRAYSIZE(GKeyNames)); const char* ImGui::GetKeyName(ImGuiKey key) { - ImGuiContext& g = *GImGui; + if (key == ImGuiKey_None) + return "None"; #ifdef IMGUI_DISABLE_OBSOLETE_KEYIO - IM_ASSERT((IsNamedKeyOrModKey(key) || key == ImGuiKey_None) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code."); + IM_ASSERT(IsNamedKeyOrMod(key) && "Support for user key indices was dropped in favor of ImGuiKey. Please update backend and user code."); #else + ImGuiContext& g = *GImGui; if (IsLegacyKey(key)) { if (g.IO.KeyMap[key] == -1) @@ -8220,27 +8482,33 @@ const char* ImGui::GetKeyName(ImGuiKey key) key = (ImGuiKey)g.IO.KeyMap[key]; } #endif - if (key == ImGuiKey_None) - return "None"; if (key & ImGuiMod_Mask_) - key = ConvertSingleModFlagToKey(&g, key); + key = ConvertSingleModFlagToKey(key); if (!IsNamedKey(key)) return "Unknown"; return GKeyNames[key - ImGuiKey_NamedKey_BEGIN]; } -// ImGuiMod_Shortcut is translated to either Ctrl or Super. +// Return untranslated names: on macOS, Cmd key will show as Ctrl, Ctrl key will show as super. +// Lifetime of return value: valid until next call to same function. const char* ImGui::GetKeyChordName(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; - key_chord = FixupKeyChord(&g, key_chord); + + const ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); + if (IsModKey(key)) + key_chord &= ~GetModForModKey(key); // Return "Ctrl+LeftShift" instead of "Ctrl+Shift+LeftShift" ImFormatString(g.TempKeychordName, IM_ARRAYSIZE(g.TempKeychordName), "%s%s%s%s%s", (key_chord & ImGuiMod_Ctrl) ? "Ctrl+" : "", (key_chord & ImGuiMod_Shift) ? "Shift+" : "", (key_chord & ImGuiMod_Alt) ? "Alt+" : "", - (key_chord & ImGuiMod_Super) ? (g.IO.ConfigMacOSXBehaviors ? "Cmd+" : "Super+") : "", - GetKeyName((ImGuiKey)(key_chord & ~ImGuiMod_Mask_))); + (key_chord & ImGuiMod_Super) ? "Super+" : "", + (key != ImGuiKey_None || key_chord == ImGuiKey_None) ? GetKeyName(key) : ""); + size_t len; + if (key == ImGuiKey_None && key_chord != 0) + if ((len = strlen(g.TempKeychordName)) != 0) // Remove trailing '+' + g.TempKeychordName[len - 1] = 0; return g.TempKeychordName; } @@ -8310,9 +8578,9 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) routing_entry = &rt->Entries[old_routing_idx]; routing_entry->RoutingCurrScore = routing_entry->RoutingNextScore; routing_entry->RoutingCurr = routing_entry->RoutingNext; // Update entry - routing_entry->RoutingNext = ImGuiKeyOwner_None; + routing_entry->RoutingNext = ImGuiKeyOwner_NoOwner; routing_entry->RoutingNextScore = 255; - if (routing_entry->RoutingCurr == ImGuiKeyOwner_None) + if (routing_entry->RoutingCurr == ImGuiKeyOwner_NoOwner) continue; rt->EntriesNext.push_back(*routing_entry); // Write alive ones into new buffer @@ -8321,7 +8589,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) if (routing_entry->Mods == g.IO.KeyMods) { ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); - if (owner_data->OwnerCurr == ImGuiKeyOwner_None) + if (owner_data->OwnerCurr == ImGuiKeyOwner_NoOwner) { owner_data->OwnerCurr = routing_entry->RoutingCurr; //IMGUI_DEBUG_LOG("SetKeyOwner(%s, owner_id=0x%08X) via Routing\n", GetKeyName(key), routing_entry->RoutingCurr); @@ -8341,7 +8609,7 @@ static void ImGui::UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt) static inline ImGuiID GetRoutingIdFromOwnerId(ImGuiID owner_id) { ImGuiContext& g = *GImGui; - return (owner_id != ImGuiKeyOwner_None && owner_id != ImGuiKeyOwner_Any) ? owner_id : g.CurrentFocusScopeId; + return (owner_id != ImGuiKeyOwner_NoOwner && owner_id != ImGuiKeyOwner_Any) ? owner_id : g.CurrentFocusScopeId; } ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) @@ -8358,8 +8626,8 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); if (key == ImGuiKey_None) - key = ConvertSingleModFlagToKey(&g, mods); - IM_ASSERT(IsNamedKey(key) && (key_chord & ImGuiMod_Shortcut) == 0); // Please call ConvertShortcutMod() in calling function. + key = ConvertSingleModFlagToKey(mods); + IM_ASSERT(IsNamedKey(key)); // Get (in the majority of case, the linked list will have one element so this should be 2 reads. // Subsequent elements will be contiguous in memory as list is sorted/rebuilt in NewFrame). @@ -8381,19 +8649,18 @@ ImGuiKeyRoutingData* ImGui::GetShortcutRoutingData(ImGuiKeyChord key_chord) } // Current score encoding (lower is highest priority): -// - 0: ImGuiInputFlags_RouteGlobalHigh -// - 1: ImGuiInputFlags_RouteFocused (if item active) -// - 2: ImGuiInputFlags_RouteGlobal +// - 0: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverActive +// - 1: ImGuiInputFlags_ActiveItem or ImGuiInputFlags_RouteFocused (if item active) +// - 2: ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused // - 3+: ImGuiInputFlags_RouteFocused (if window in focus-stack) -// - 254: ImGuiInputFlags_RouteGlobalLow +// - 254: ImGuiInputFlags_RouteGlobal // - 255: never route // 'flags' should include an explicit routing policy static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInputFlags flags) { + ImGuiContext& g = *GImGui; if (flags & ImGuiInputFlags_RouteFocused) { - ImGuiContext& g = *GImGui; - // ActiveID gets top priority // (we don't check g.ActiveIdUsingAllKeys here. Routing is applied but if input ownership is tested later it may discard it) if (owner_id != 0 && g.ActiveId == owner_id) @@ -8411,15 +8678,23 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput for (int index_in_focus_path = 0; index_in_focus_path < g.NavFocusRoute.Size; index_in_focus_path++) if (g.NavFocusRoute.Data[index_in_focus_path].ID == focus_scope_id) return 3 + index_in_focus_path; - return 255; } - - // ImGuiInputFlags_RouteGlobalHigh is default, so calls without flags are not conditional - if (flags & ImGuiInputFlags_RouteGlobal) - return 2; - if (flags & ImGuiInputFlags_RouteGlobalLow) + else if (flags & ImGuiInputFlags_RouteActive) + { + if (owner_id != 0 && g.ActiveId == owner_id) + return 1; + return 255; + } + else if (flags & ImGuiInputFlags_RouteGlobal) + { + if (flags & ImGuiInputFlags_RouteOverActive) + return 0; + if (flags & ImGuiInputFlags_RouteOverFocused) + return 2; return 254; + } + IM_ASSERT(0); return 0; } @@ -8432,7 +8707,7 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord) // When the right mods are pressed it cannot be a char input so we won't filter the shortcut out. ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); - const bool ignore_char_inputs = ((mods & ImGuiMod_Ctrl) && !(mods & ImGuiMod_Alt)) || (g.IO.ConfigMacOSXBehaviors && (mods & ImGuiMod_Super)); + const bool ignore_char_inputs = ((mods & ImGuiMod_Ctrl) && !(mods & ImGuiMod_Alt)) || (g.IO.ConfigMacOSXBehaviors && (mods & ImGuiMod_Ctrl)); if (ignore_char_inputs) return false; @@ -8446,17 +8721,19 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord) // - Routes and key ownership are attributed at the beginning of next frame based on best score and mod state. // (Conceptually this does a "Submit for next frame" + "Test for current frame". // As such, it could be called TrySetXXX or SubmitXXX, or the Submit and Test operations should be separate.) -bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) { ImGuiContext& g = *GImGui; - if ((flags & ImGuiInputFlags_RouteMask_) == 0) - flags |= ImGuiInputFlags_RouteGlobalHigh; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut() + if ((flags & ImGuiInputFlags_RouteTypeMask_) == 0) + flags |= ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive; // IMPORTANT: This is the default for SetShortcutRouting() but NOT Shortcut() else - IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteMask_)); // Check that only 1 routing flag is used - IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_None); + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiInputFlags_RouteTypeMask_)); // Check that only 1 routing flag is used + IM_ASSERT(owner_id != ImGuiKeyOwner_Any && owner_id != ImGuiKeyOwner_NoOwner); + if (flags & (ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused)) + IM_ASSERT(flags & ImGuiInputFlags_RouteGlobal); - // Convert ImGuiMod_Shortcut and add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. - key_chord = FixupKeyChord(&g, key_chord); + // Add ImGuiMod_XXXX when a corresponding ImGuiKey_LeftXXX/ImGuiKey_RightXXX is specified. + key_chord = FixupKeyChord(key_chord); // [DEBUG] Debug break requested by user if (g.DebugBreakInShortcutRouting == key_chord) @@ -8469,38 +8746,45 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI // Note how ImGuiInputFlags_RouteAlways won't set routing and thus won't set owner. May want to rework this? if (flags & ImGuiInputFlags_RouteAlways) { - IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> always\n", GetKeyChordName(key_chord), owner_id, flags); + IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> always, no register\n", GetKeyChordName(key_chord), flags, owner_id); return true; } - // Specific culling when there's an active. + // Specific culling when there's an active item. if (g.ActiveId != 0 && g.ActiveId != owner_id) { + if (flags & ImGuiInputFlags_RouteActive) + return false; + // Cull shortcuts with no modifiers when it could generate a character. // e.g. Shortcut(ImGuiKey_G) also generates 'g' character, should not trigger when InputText() is active. // but Shortcut(Ctrl+G) should generally trigger when InputText() is active. // TL;DR: lettered shortcut with no mods or with only Alt mod will not trigger while an item reading text input is active. // (We cannot filter based on io.InputQueueCharacters[] contents because of trickling and key<>chars submission order are undefined) - if ((flags & ImGuiInputFlags_RouteFocused) && g.IO.WantTextInput && IsKeyChordPotentiallyCharInput(key_chord)) + if (g.IO.WantTextInput && IsKeyChordPotentiallyCharInput(key_chord)) { - IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> filtered as potential char input\n", GetKeyChordName(key_chord), owner_id, flags); + IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> filtered as potential char input\n", GetKeyChordName(key_chord), flags, owner_id); return false; } // ActiveIdUsingAllKeyboardKeys trumps all for ActiveId - if ((flags & ImGuiInputFlags_RouteGlobalHigh) == 0 && g.ActiveIdUsingAllKeyboardKeys) + if ((flags & ImGuiInputFlags_RouteOverActive) == 0 && g.ActiveIdUsingAllKeyboardKeys) { ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); if (key == ImGuiKey_None) - key = ConvertSingleModFlagToKey(&g, (ImGuiKey)(key_chord & ImGuiMod_Mask_)); + key = ConvertSingleModFlagToKey((ImGuiKey)(key_chord & ImGuiMod_Mask_)); if (key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END) return false; } } - // FIXME-SHORTCUT: A way to configure the location/focus-scope to test would render this more flexible. - const int score = CalcRoutingScore(g.CurrentFocusScopeId, owner_id, flags); - IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, owner_id=0x%08X, flags=%04X) -> score %d\n", GetKeyChordName(key_chord), owner_id, flags, score); + // Where do we evaluate route for? + ImGuiID focus_scope_id = g.CurrentFocusScopeId; + if (flags & ImGuiInputFlags_RouteFromRootWindow) + focus_scope_id = g.CurrentWindow->RootWindow->ID; // See PushFocusScope() call in Begin() + + const int score = CalcRoutingScore(focus_scope_id, owner_id, flags); + IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> score %d\n", GetKeyChordName(key_chord), flags, owner_id, score); if (score == 255) return false; @@ -8524,9 +8808,8 @@ bool ImGui::SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiI // Note: this cannot be turned into GetShortcutRouting() because we do the owner_id->routing_id translation, name would be more misleading. bool ImGui::TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id) { - ImGuiContext& g = *GImGui; const ImGuiID routing_id = GetRoutingIdFromOwnerId(owner_id); - key_chord = FixupKeyChord(&g, key_chord); + key_chord = FixupKeyChord(key_chord); ImGuiKeyRoutingData* routing_data = GetShortcutRoutingData(key_chord); // FIXME: Could avoid creating entry. return routing_data->RoutingCurr == routing_id; } @@ -8550,11 +8833,11 @@ bool ImGui::IsKeyDown(ImGuiKey key, ImGuiID owner_id) bool ImGui::IsKeyPressed(ImGuiKey key, bool repeat) { - return IsKeyPressed(key, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); + return IsKeyPressed(key, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any); } // Important: unless legacy IsKeyPressed(ImGuiKey, bool repeat=true) which DEFAULT to repeat, this requires EXPLICIT repeat. -bool ImGui::IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags) +bool ImGui::IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id) { const ImGuiKeyData* key_data = GetKeyData(key); if (!key_data->Down) // In theory this should already be encoded as (DownDuration < 0.0f), but testing this facilitates eating mechanism (until we finish work on key ownership) @@ -8624,10 +8907,10 @@ bool ImGui::IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id) bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat) { - return IsMouseClicked(button, ImGuiKeyOwner_Any, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None); + return IsMouseClicked(button, repeat ? ImGuiInputFlags_Repeat : ImGuiInputFlags_None, ImGuiKeyOwner_Any); } -bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags) +bool ImGui::IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id) { ImGuiContext& g = *GImGui; IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); @@ -8953,7 +9236,7 @@ static void ImGui::UpdateKeyboardInputs() ImGuiKeyOwnerData* owner_data = &g.KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; owner_data->OwnerCurr = owner_data->OwnerNext; if (!key_data->Down) // Important: ownership is released on the frame after a release. Ensure a 'MouseDown -> CloseWindow -> MouseUp' chain doesn't lead to someone else seeing the MouseUp. - owner_data->OwnerNext = ImGuiKeyOwner_None; + owner_data->OwnerNext = ImGuiKeyOwner_NoOwner; owner_data->LockThisFrame = owner_data->LockUntilRelease = owner_data->LockUntilRelease && key_data->Down; // Clear LockUntilRelease when key is not Down anymore } @@ -9109,8 +9392,8 @@ void ImGui::UpdateMouseWheel() } ImVec2 wheel; - wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_None) ? g.IO.MouseWheelH : 0.0f; - wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_None) ? g.IO.MouseWheel : 0.0f; + wheel.x = TestKeyOwner(ImGuiKey_MouseWheelX, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheelH : 0.0f; + wheel.y = TestKeyOwner(ImGuiKey_MouseWheelY, ImGuiKeyOwner_NoOwner) ? g.IO.MouseWheel : 0.0f; //IMGUI_DEBUG_LOG("MouseWheel X:%.3f Y:%.3f\n", wheel_x, wheel_y); ImGuiWindow* mouse_window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow; @@ -9197,7 +9480,7 @@ void ImGui::SetNextFrameWantCaptureMouse(bool want_capture_mouse) #ifndef IMGUI_DISABLE_DEBUG_TOOLS static const char* GetInputSourceName(ImGuiInputSource source) { - const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad", "Clipboard" }; + const char* input_source_names[] = { "None", "Mouse", "Keyboard", "Gamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT && source >= 0 && source < ImGuiInputSource_COUNT); return input_source_names[source]; } @@ -9348,8 +9631,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) ImGuiID ImGui::GetKeyOwner(ImGuiKey key) { - if (!IsNamedKeyOrModKey(key)) - return ImGuiKeyOwner_None; + if (!IsNamedKeyOrMod(key)) + return ImGuiKeyOwner_NoOwner; ImGuiContext& g = *GImGui; ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); @@ -9357,7 +9640,7 @@ ImGuiID ImGui::GetKeyOwner(ImGuiKey key) if (g.ActiveIdUsingAllKeyboardKeys && owner_id != g.ActiveId && owner_id != ImGuiKeyOwner_Any) if (key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END) - return ImGuiKeyOwner_None; + return ImGuiKeyOwner_NoOwner; return owner_id; } @@ -9368,7 +9651,7 @@ ImGuiID ImGui::GetKeyOwner(ImGuiKey key) // All paths are also testing for key not being locked, for the rare cases that key have been locked with using ImGuiInputFlags_LockXXX flags. bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id) { - if (!IsNamedKeyOrModKey(key)) + if (!IsNamedKeyOrMod(key)) return true; ImGuiContext& g = *GImGui; @@ -9387,7 +9670,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id) { if (owner_data->LockThisFrame) return false; - if (owner_data->OwnerCurr != ImGuiKeyOwner_None) + if (owner_data->OwnerCurr != ImGuiKeyOwner_NoOwner) return false; } @@ -9402,7 +9685,7 @@ bool ImGui::TestKeyOwner(ImGuiKey key, ImGuiID owner_id) void ImGui::SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; - IM_ASSERT(IsNamedKeyOrModKey(key) && (owner_id != ImGuiKeyOwner_Any || (flags & (ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease)))); // Can only use _Any with _LockXXX flags (to eat a key away without an ID to retrieve it) + IM_ASSERT(IsNamedKeyOrMod(key) && (owner_id != ImGuiKeyOwner_Any || (flags & (ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease)))); // Can only use _Any with _LockXXX flags (to eat a key away without an ID to retrieve it) IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetKeyOwner) == 0); // Passing flags not supported by this function! //IMGUI_DEBUG_LOG("SetKeyOwner(%s, owner_id=0x%08X, flags=%08X)\n", GetKeyName(key), owner_id, flags); @@ -9422,7 +9705,6 @@ void ImGui::SetKeyOwnersForKeyChord(ImGuiKeyChord key_chord, ImGuiID owner_id, I if (key_chord & ImGuiMod_Shift) { SetKeyOwner(ImGuiMod_Shift, owner_id, flags); } if (key_chord & ImGuiMod_Alt) { SetKeyOwner(ImGuiMod_Alt, owner_id, flags); } if (key_chord & ImGuiMod_Super) { SetKeyOwner(ImGuiMod_Super, owner_id, flags); } - if (key_chord & ImGuiMod_Shortcut) { SetKeyOwner(ImGuiMod_Shortcut, owner_id, flags); } if (key_chord & ~ImGuiMod_Mask_) { SetKeyOwner((ImGuiKey)(key_chord & ~ImGuiMod_Mask_), owner_id, flags); } } @@ -9450,14 +9732,14 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags) // This is the only public API until we expose owner_id versions of the API as replacements. bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord) { - return IsKeyChordPressed(key_chord, 0, ImGuiInputFlags_None); + return IsKeyChordPressed(key_chord, ImGuiInputFlags_None, ImGuiKeyOwner_Any); } // This is equivalent to comparing KeyMods + doing a IsKeyPressed() -bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) { ImGuiContext& g = *GImGui; - key_chord = FixupKeyChord(&g, key_chord); + key_chord = FixupKeyChord(key_chord); ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_); if (g.IO.KeyMods != mods) return false; @@ -9465,35 +9747,63 @@ bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiIn // Special storage location for mods ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_); if (key == ImGuiKey_None) - key = ConvertSingleModFlagToKey(&g, mods); - if (!IsKeyPressed(key, owner_id, (flags & ImGuiInputFlags_RepeatMask_))) + key = ConvertSingleModFlagToKey(mods); + if (!IsKeyPressed(key, (flags & ImGuiInputFlags_RepeatMask_), owner_id)) return false; return true; } -void ImGui::SetNextItemShortcut(ImGuiKeyChord key_chord) +void ImGui::SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags) { ImGuiContext& g = *GImGui; g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasShortcut; g.NextItemData.Shortcut = key_chord; + g.NextItemData.ShortcutFlags = flags; } -bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags) +void ImGui::ItemHandleShortcut(ImGuiID id) +{ + ImGuiContext& g = *GImGui; + ImGuiInputFlags flags = g.NextItemData.ShortcutFlags; + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedBySetNextItemShortcut) == 0); // Passing flags not supported by SetNextItemShortcut()! + + if (flags & ImGuiInputFlags_Tooltip) + { + g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HasShortcut; + g.LastItemData.Shortcut = g.NextItemData.Shortcut; + } + if (!Shortcut(g.NextItemData.Shortcut, flags & ImGuiInputFlags_SupportedByShortcut, id) || g.NavActivateId != 0) + return; + + // FIXME: Generalize Activation queue? + g.NavActivateId = id; // Will effectively disable clipping. + g.NavActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_FromShortcut; + //if (g.ActiveId == 0 || g.ActiveId == id) + g.NavActivateDownId = g.NavActivatePressedId = id; + NavHighlightActivated(id); +} + +bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags) +{ + return Shortcut(key_chord, flags, ImGuiKeyOwner_Any); +} + +bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id) { //ImGuiContext& g = *GImGui; - //IMGUI_DEBUG_LOG("Shortcut(%s, owner_id=0x%08X, flags=%X)\n", GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), owner_id, flags); + //IMGUI_DEBUG_LOG("Shortcut(%s, flags=%X, owner_id=0x%08X)\n", GetKeyChordName(key_chord, g.TempBuffer.Data, g.TempBuffer.Size), flags, owner_id); // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any. - if ((flags & ImGuiInputFlags_RouteMask_) == 0) + if ((flags & ImGuiInputFlags_RouteTypeMask_) == 0) flags |= ImGuiInputFlags_RouteFocused; // Using 'owner_id == ImGuiKeyOwner_Any/0': auto-assign an owner based on current focus scope (each window has its focus scope by default) // Effectively makes Shortcut() always input-owner aware. - if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_None) + if (owner_id == ImGuiKeyOwner_Any || owner_id == ImGuiKeyOwner_NoOwner) owner_id = GetRoutingIdFromOwnerId(owner_id); // Submit route - if (!SetShortcutRouting(key_chord, owner_id, flags)) + if (!SetShortcutRouting(key_chord, flags, owner_id)) return false; // Default repeat behavior for Shortcut() @@ -9501,8 +9811,12 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags if ((flags & ImGuiInputFlags_Repeat) != 0 && (flags & ImGuiInputFlags_RepeatUntilMask_) == 0) flags |= ImGuiInputFlags_RepeatUntilKeyModsChange; - if (!IsKeyChordPressed(key_chord, owner_id, flags)) + if (!IsKeyChordPressed(key_chord, flags, owner_id)) return false; + + // Claim mods during the press + SetKeyOwnersForKeyChord(key_chord & ImGuiMod_Mask_, owner_id); + IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function! return true; } @@ -9512,24 +9826,26 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags // [SECTION] ERROR CHECKING //----------------------------------------------------------------------------- -// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. +// Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues. +// Called by IMGUI_CHECKVERSION(). // Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit -// If this triggers you have an issue: -// - Most commonly: mismatched headers and compiled code version. -// - Or: mismatched configuration #define, compilation settings, packing pragma etc. -// The configuration settings mentioned in imconfig.h must be set for all compilation units involved with Dear ImGui, -// which is way it is required you put them in your imconfig file (and not just before including imgui.h). -// Otherwise it is possible that different compilation units would see different structure layout +// If this triggers you have mismatched headers and compiled code versions. +// - It could be because of a build issue (using new headers with old compiled code) +// - It could be because of mismatched configuration #define, compilation settings, packing pragma etc. +// THE CONFIGURATION SETTINGS MENTIONED IN imconfig.h MUST BE SET FOR ALL COMPILATION UNITS INVOLVED WITH DEAR IMGUI. +// Which is why it is required you put them in your imconfig file (and NOT only before including imgui.h). +// Otherwise it is possible that different compilation units would see different structure layout. +// If you don't want to modify imconfig.h you can use the IMGUI_USER_CONFIG define to change filename. bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx) { bool error = false; if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); } - if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } + if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } - if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } - if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } - if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } - if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } + if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } + if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } + if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } + if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } return !error; } @@ -9605,10 +9921,6 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); #endif - - // Check: the io.ConfigWindowsResizeFromEdges option requires backend to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly. - if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors)) - g.IO.ConfigWindowsResizeFromEdges = false; } static void ImGui::ErrorCheckEndFrameSanityChecks() @@ -9716,7 +10028,13 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044 { if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name); - EndDisabled(); + if (g.CurrentItemFlags & ImGuiItemFlags_Disabled) + EndDisabled(); + else + { + EndDisabledOverrideReenable(); + g.CurrentWindowStack.back().DisabledOverrideReenable = false; + } } while (g.ColorStack.Size > stack_sizes->SizeOfColorStack) { @@ -9788,7 +10106,6 @@ void ImGuiStackSizes::CompareWithContextState(ImGuiContext* ctx) // [SECTION] ITEM SUBMISSION //----------------------------------------------------------------------------- // - KeepAliveID() -// - ItemHandleShortcut() [Internal] // - ItemAdd() //----------------------------------------------------------------------------- @@ -9802,24 +10119,11 @@ void ImGui::KeepAliveID(ImGuiID id) g.ActiveIdPreviousFrameIsAlive = true; } -static void ItemHandleShortcut(ImGuiID id) -{ - // FIXME: Generalize Activation queue? - ImGuiContext& g = *GImGui; - if (ImGui::Shortcut(g.NextItemData.Shortcut, id, ImGuiInputFlags_None) && g.NavActivateId == 0) - { - g.NavActivateId = id; // Will effectively disable clipping. - g.NavActivateFlags = ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_FromShortcut; - if (g.ActiveId == 0 || g.ActiveId == id) - g.NavActivateDownId = g.NavActivatePressedId = id; - ImGui::NavHighlightActivated(id); - } -} - // 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. // THIS IS IN THE PERFORMANCE CRITICAL PATH (UNTIL THE CLIPPING TEST AND EARLY-RETURN) +IM_MSVC_RUNTIME_CHECKS_OFF bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGuiItemFlags extra_flags) { ImGuiContext& g = *GImGui; @@ -9872,15 +10176,12 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu #endif // Clipping test - // (this is a modified copy of IsClippedEx() so we can reuse the is_rect_visible value) - //const bool is_clipped = IsClippedEx(bb, id); - //if (is_clipped) - // return false; + // (this is an inline copy of IsClippedEx() so we can reuse the is_rect_visible value, otherwise we'd do 'if (IsClippedEx(bb, id)) return false') // g.NavActivateId is not necessarily == g.NavId, in the case of remote activation (e.g. shortcuts) const bool is_rect_visible = bb.Overlaps(window->ClipRect); if (!is_rect_visible) if (id == 0 || (id != g.ActiveId && id != g.ActiveIdPreviousFrame && id != g.NavId && id != g.NavActivateId)) - if (!g.LogEnabled) + if (!g.ItemUnclipByLog) return false; // [DEBUG] @@ -9907,7 +10208,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredRect; return true; } - +IM_MSVC_RUNTIME_CHECKS_RESTORE //----------------------------------------------------------------------------- // [SECTION] LAYOUT @@ -9944,6 +10245,7 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg, ImGu // Register minimum needed size so it can extend the bounding box used for auto-fit calculation. // See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different. // THIS IS IN THE PERFORMANCE CRITICAL PATH. +IM_MSVC_RUNTIME_CHECKS_OFF void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) { ImGuiContext& g = *GImGui; @@ -9979,6 +10281,7 @@ void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) SameLine(); } +IM_MSVC_RUNTIME_CHECKS_RESTORE // Gets back to previous line and continue with horizontal layout // offset_from_start_x == 0 : follow right after previous item @@ -10776,7 +11079,7 @@ void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags) ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. popup_ref.PopupId = id; popup_ref.Window = NULL; - popup_ref.BackupNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type). + popup_ref.RestoreNavWindow = g.NavWindow; // When popup closes focus may be restored to NavWindow (depend on window type). popup_ref.OpenFrameCount = g.FrameCount; popup_ref.OpenParentId = parent_window->IDStack.back(); popup_ref.OpenPopupPos = NavCalcPreferredRefPos(); @@ -10825,6 +11128,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to return; // Don't close our own child popup windows. + //IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupsOverWindow(\"%s\") restore_under=%d\n", ref_window ? ref_window->Name : "", restore_focus_to_window_under_popup); int popup_count_to_keep = 0; if (ref_window) { @@ -10881,18 +11185,19 @@ void ImGui::ClosePopupsExceptModals() void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup) { ImGuiContext& g = *GImGui; - IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupToLevel(%d), restore_focus_to_window_under_popup=%d\n", remaining, restore_focus_to_window_under_popup); + IMGUI_DEBUG_LOG_POPUP("[popup] ClosePopupToLevel(%d), restore_under=%d\n", remaining, restore_focus_to_window_under_popup); IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size); // Trim open popup stack - ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window; - ImGuiWindow* popup_backup_nav_window = g.OpenPopupStack[remaining].BackupNavWindow; + ImGuiPopupData prev_popup = g.OpenPopupStack[remaining]; g.OpenPopupStack.resize(remaining); - if (restore_focus_to_window_under_popup) + // Restore focus (unless popup window was not yet submitted, and didn't have a chance to take focus anyhow. See #7325 for an edge case) + if (restore_focus_to_window_under_popup && prev_popup.Window) { - ImGuiWindow* focus_window = (popup_window && popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : popup_backup_nav_window; - if (focus_window && !focus_window->WasActive && popup_window) + ImGuiWindow* popup_window = prev_popup.Window; + ImGuiWindow* focus_window = (popup_window->Flags & ImGuiWindowFlags_ChildMenu) ? popup_window->ParentWindow : prev_popup.RestoreNavWindow; + if (focus_window && !focus_window->WasActive) FocusTopMostWindowUnderOne(popup_window, NULL, NULL, ImGuiFocusRequestFlags_RestoreFocusedChild); // Fallback else FocusWindow(focus_window, (g.NavLayer == ImGuiNavLayer_Main) ? ImGuiFocusRequestFlags_RestoreFocusedChild : ImGuiFocusRequestFlags_None); @@ -10930,8 +11235,8 @@ void ImGui::CloseCurrentPopup() window->DC.NavHideHighlightOneFrame = true; } -// Attention! BeginPopup() adds default flags which BeginPopupEx()! -bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) +// Attention! BeginPopup() adds default flags when calling BeginPopupEx()! +bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags) { ImGuiContext& g = *GImGui; if (!IsPopupOpen(id, ImGuiPopupFlags_None)) @@ -10941,13 +11246,12 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags flags) } char name[20]; - if (flags & ImGuiWindowFlags_ChildMenu) + if (extra_window_flags & ImGuiWindowFlags_ChildMenu) ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginMenuDepth); // Recycle windows based on depth else ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame - flags |= ImGuiWindowFlags_Popup; - bool is_open = Begin(name, NULL, flags); + bool is_open = Begin(name, NULL, extra_window_flags | ImGuiWindowFlags_Popup); if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) EndPopup(); @@ -11814,7 +12118,10 @@ static ImVec2 ImGui::NavCalcPreferredRefPos() { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.NavWindow; - if (g.NavDisableHighlight || !g.NavDisableMouseHover || !window) + const bool activated_shortcut = g.ActiveId != 0 && g.ActiveIdFromShortcut && g.ActiveId == g.LastItemData.ID; + + // Testing for !activated_shortcut here could in theory be removed if we decided that activating a remote shortcut altered one of the g.NavDisableXXX flag. + if ((g.NavDisableHighlight || !g.NavDisableMouseHover || !window) && !activated_shortcut) { // Mouse (we need a fallback in case the mouse becomes invalid after being used) // The +1.0f offset when stored by OpenPopupEx() allows reopening this or another popup (same or another mouse button) while not moving the mouse, it is pretty standard. @@ -11825,14 +12132,19 @@ static ImVec2 ImGui::NavCalcPreferredRefPos() else { // When navigation is active and mouse is disabled, pick a position around the bottom left of the currently navigated item + ImRect ref_rect; + if (activated_shortcut) + ref_rect = g.LastItemData.NavRect; + else + ref_rect = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]); + // Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?) - ImRect rect_rel = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]); if (window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX)) { ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); - rect_rel.Translate(window->Scroll - next_scroll); + ref_rect.Translate(window->Scroll - next_scroll); } - ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); + ImVec2 pos = ImVec2(ref_rect.Min.x + ImMin(g.Style.FramePadding.x * 4, ref_rect.GetWidth()), ref_rect.Max.y - ImMin(g.Style.FramePadding.y, ref_rect.GetHeight())); ImGuiViewport* viewport = GetMainViewport(); return ImTrunc(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImTrunc() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta. } @@ -11927,10 +12239,10 @@ static void ImGui::NavUpdate() g.NavActivateFlags = ImGuiActivateFlags_None; if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) { - const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space, ImGuiKeyOwner_None)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_None)); - const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, ImGuiKeyOwner_None)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_None))); - const bool input_down = (nav_keyboard_active && (IsKeyDown(ImGuiKey_Enter, ImGuiKeyOwner_None) || IsKeyDown(ImGuiKey_KeypadEnter, ImGuiKeyOwner_None))) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput, ImGuiKeyOwner_None)); - const bool input_pressed = input_down && ((nav_keyboard_active && (IsKeyPressed(ImGuiKey_Enter, ImGuiKeyOwner_None) || IsKeyPressed(ImGuiKey_KeypadEnter, ImGuiKeyOwner_None))) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, ImGuiKeyOwner_None))); + const bool activate_down = (nav_keyboard_active && IsKeyDown(ImGuiKey_Space, ImGuiKeyOwner_NoOwner)) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadActivate, ImGuiKeyOwner_NoOwner)); + const bool activate_pressed = activate_down && ((nav_keyboard_active && IsKeyPressed(ImGuiKey_Space, 0, ImGuiKeyOwner_NoOwner)) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadActivate, 0, ImGuiKeyOwner_NoOwner))); + const bool input_down = (nav_keyboard_active && (IsKeyDown(ImGuiKey_Enter, ImGuiKeyOwner_NoOwner) || IsKeyDown(ImGuiKey_KeypadEnter, ImGuiKeyOwner_NoOwner))) || (nav_gamepad_active && IsKeyDown(ImGuiKey_NavGamepadInput, ImGuiKeyOwner_NoOwner)); + const bool input_pressed = input_down && ((nav_keyboard_active && (IsKeyPressed(ImGuiKey_Enter, 0, ImGuiKeyOwner_NoOwner) || IsKeyPressed(ImGuiKey_KeypadEnter, 0, ImGuiKeyOwner_NoOwner))) || (nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadInput, 0, ImGuiKeyOwner_NoOwner))); if (g.ActiveId == 0 && activate_pressed) { g.NavActivateId = g.NavId; @@ -12103,11 +12415,11 @@ void ImGui::NavUpdateCreateMoveRequest() g.NavMoveScrollFlags = ImGuiScrollFlags_None; if (window && !g.NavWindowingTarget && !(window->Flags & ImGuiWindowFlags_NoNavInputs)) { - const ImGuiInputFlags repeat_mode = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateNavMove; - if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadLeft, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_LeftArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Left; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadRight, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_RightArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Right; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadUp, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_UpArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Up; } - if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadDown, ImGuiKeyOwner_None, repeat_mode)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_DownArrow, ImGuiKeyOwner_None, repeat_mode)))) { g.NavMoveDir = ImGuiDir_Down; } + const ImGuiInputFlags repeat_mode = ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateNavMove; + if (!IsActiveIdUsingNavDir(ImGuiDir_Left) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadLeft, repeat_mode, ImGuiKeyOwner_NoOwner)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_LeftArrow, repeat_mode, ImGuiKeyOwner_NoOwner)))) { g.NavMoveDir = ImGuiDir_Left; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Right) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadRight, repeat_mode, ImGuiKeyOwner_NoOwner)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_RightArrow, repeat_mode, ImGuiKeyOwner_NoOwner)))) { g.NavMoveDir = ImGuiDir_Right; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Up) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadUp, repeat_mode, ImGuiKeyOwner_NoOwner)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_UpArrow, repeat_mode, ImGuiKeyOwner_NoOwner)))) { g.NavMoveDir = ImGuiDir_Up; } + if (!IsActiveIdUsingNavDir(ImGuiDir_Down) && ((nav_gamepad_active && IsKeyPressed(ImGuiKey_GamepadDpadDown, repeat_mode, ImGuiKeyOwner_NoOwner)) || (nav_keyboard_active && IsKeyPressed(ImGuiKey_DownArrow, repeat_mode, ImGuiKeyOwner_NoOwner)))) { g.NavMoveDir = ImGuiDir_Down; } } g.NavMoveClipDir = g.NavMoveDir; g.NavScoringNoClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX); @@ -12203,7 +12515,7 @@ void ImGui::NavUpdateCreateTabbingRequest() if (window == NULL || g.NavWindowingTarget != NULL || (window->Flags & ImGuiWindowFlags_NoNavInputs)) return; - const bool tab_pressed = IsKeyPressed(ImGuiKey_Tab, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat) && !g.IO.KeyCtrl && !g.IO.KeyAlt; + const bool tab_pressed = IsKeyPressed(ImGuiKey_Tab, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner) && !g.IO.KeyCtrl && !g.IO.KeyAlt; if (!tab_pressed) return; @@ -12284,8 +12596,10 @@ void ImGui::NavMoveRequestApplyResult() g.NavLastValidSelectionUserData = ImGuiSelectionUserData_Invalid; } - // FIXME: Could become optional e.g. ImGuiNavMoveFlags_NoClearActiveId if we later want to apply navigation requests without altering active input. - if (g.ActiveId != result->ID) + // Clear active id unless requested not to + // FIXME: ImGuiNavMoveFlags_NoClearActiveId is currently unused as we don't have a clear strategy to preserve active id after interaction, + // so this is mostly provided as a gateway for further experiments (see #1418, #2890) + if (g.ActiveId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoClearActiveId) == 0) ClearActiveID(); // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) @@ -12339,7 +12653,7 @@ static void ImGui::NavUpdateCancelRequest() ImGuiContext& g = *GImGui; const bool nav_gamepad_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (g.IO.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0; - if (!(nav_keyboard_active && IsKeyPressed(ImGuiKey_Escape, ImGuiKeyOwner_None)) && !(nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadCancel, ImGuiKeyOwner_None))) + if (!(nav_keyboard_active && IsKeyPressed(ImGuiKey_Escape, 0, ImGuiKeyOwner_NoOwner)) && !(nav_gamepad_active && IsKeyPressed(ImGuiKey_NavGamepadCancel, 0, ImGuiKeyOwner_NoOwner))) return; IMGUI_DEBUG_LOG_NAV("[nav] NavUpdateCancelRequest()\n"); @@ -12388,10 +12702,10 @@ static float ImGui::NavUpdatePageUpPageDown() if ((window->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL) return 0.0f; - const bool page_up_held = IsKeyDown(ImGuiKey_PageUp, ImGuiKeyOwner_None); - const bool page_down_held = IsKeyDown(ImGuiKey_PageDown, ImGuiKeyOwner_None); - const bool home_pressed = IsKeyPressed(ImGuiKey_Home, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat); - const bool end_pressed = IsKeyPressed(ImGuiKey_End, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat); + const bool page_up_held = IsKeyDown(ImGuiKey_PageUp, ImGuiKeyOwner_NoOwner); + const bool page_down_held = IsKeyDown(ImGuiKey_PageDown, ImGuiKeyOwner_NoOwner); + const bool home_pressed = IsKeyPressed(ImGuiKey_Home, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner); + const bool end_pressed = IsKeyPressed(ImGuiKey_End, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner); if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out return 0.0f; @@ -12401,9 +12715,9 @@ static float ImGui::NavUpdatePageUpPageDown() if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavWindowHasScrollY) { // Fallback manual-scroll when window has no navigable item - if (IsKeyPressed(ImGuiKey_PageUp, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat)) + if (IsKeyPressed(ImGuiKey_PageUp, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner)) SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); - else if (IsKeyPressed(ImGuiKey_PageDown, ImGuiKeyOwner_None, ImGuiInputFlags_Repeat)) + else if (IsKeyPressed(ImGuiKey_PageDown, ImGuiInputFlags_Repeat, ImGuiKeyOwner_NoOwner)) SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); else if (home_pressed) SetScrollY(window, 0.0f); @@ -12596,9 +12910,9 @@ static void ImGui::NavUpdateWindowing() const ImGuiID owner_id = ImHashStr("###NavUpdateWindowing"); const 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 keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, owner_id, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways); - const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, owner_id, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways); - const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && IsKeyPressed(ImGuiKey_NavGamepadMenu, 0, ImGuiInputFlags_None); + const bool keyboard_next_window = allow_windowing && g.ConfigNavWindowingKeyNext && Shortcut(g.ConfigNavWindowingKeyNext, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); + const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); + const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && IsKeyPressed(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_None); const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard! if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) @@ -12609,7 +12923,7 @@ static void ImGui::NavUpdateWindowing() g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; - // Register ownership of our mods. Using ImGuiInputFlags_RouteGlobalHigh in the Shortcut() calls instead would probably be correct but may have more side-effects. + // Manually register ownership of our mods. Using a global route in the Shortcut() calls instead would probably be correct but may have more side-effects. if (keyboard_next_window || keyboard_prev_window) SetKeyOwnersForKeyChord((g.ConfigNavWindowingKeyNext | g.ConfigNavWindowingKeyPrev) & ImGuiMod_Mask_, owner_id); } @@ -12657,7 +12971,7 @@ static void ImGui::NavUpdateWindowing() // Keyboard: Press and Release ALT to toggle menu layer const ImGuiKey windowing_toggle_keys[] = { ImGuiKey_LeftAlt, ImGuiKey_RightAlt }; for (ImGuiKey windowing_toggle_key : windowing_toggle_keys) - if (nav_keyboard_active && IsKeyPressed(windowing_toggle_key, ImGuiKeyOwner_None)) + if (nav_keyboard_active && IsKeyPressed(windowing_toggle_key, 0, ImGuiKeyOwner_NoOwner)) { g.NavWindowingToggleLayer = true; g.NavWindowingToggleKey = windowing_toggle_key; @@ -12672,7 +12986,7 @@ static void ImGui::NavUpdateWindowing() // We cancel toggling nav layer if an owner has claimed the key. if (io.InputQueueCharacters.Size > 0 || io.KeyCtrl || io.KeyShift || io.KeySuper) g.NavWindowingToggleLayer = false; - if (TestKeyOwner(g.NavWindowingToggleKey, ImGuiKeyOwner_None) == false || TestKeyOwner(ImGuiMod_Alt, ImGuiKeyOwner_None) == false) + if (TestKeyOwner(g.NavWindowingToggleKey, ImGuiKeyOwner_NoOwner) == false || TestKeyOwner(ImGuiMod_Alt, ImGuiKeyOwner_NoOwner) == false) g.NavWindowingToggleLayer = false; // Apply layer toggle on Alt release @@ -12820,6 +13134,8 @@ bool ImGui::IsDragDropActive() void ImGui::ClearDragDrop() { ImGuiContext& g = *GImGui; + if (g.DragDropActive) + IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] ClearDragDrop()\n"); g.DragDropActive = false; g.DragDropPayload.Clear(); g.DragDropAcceptFlags = ImGuiDragDropFlags_None; @@ -12858,7 +13174,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) bool source_drag_active = false; ImGuiID source_id = 0; ImGuiID source_parent_id = 0; - if (!(flags & ImGuiDragDropFlags_SourceExtern)) + if ((flags & ImGuiDragDropFlags_SourceExtern) == 0) { source_id = g.LastItemData.ID; if (source_id != 0) @@ -12919,43 +13235,45 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) source_drag_active = true; } - if (source_drag_active) - { - if (!g.DragDropActive) - { - IM_ASSERT(source_id != 0); - ClearDragDrop(); - ImGuiPayload& payload = g.DragDropPayload; - payload.SourceId = source_id; - payload.SourceParentId = source_parent_id; - g.DragDropActive = true; - g.DragDropSourceFlags = flags; - g.DragDropMouseButton = mouse_button; - if (payload.SourceId == g.ActiveId) - g.ActiveIdNoClearOnFocusLoss = true; - } - g.DragDropSourceFrameCount = g.FrameCount; - g.DragDropWithinSource = true; + IM_ASSERT(g.DragDropWithinTarget == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget() + if (!source_drag_active) + return false; - if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) - { - // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit) - // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents. - bool ret; - if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) - ret = BeginTooltipHidden(); - else - ret = BeginTooltip(); - IM_ASSERT(ret); // FIXME-NEWBEGIN: If this ever becomes false, we need to Begin("##Hidden", NULL, ImGuiWindowFlags_NoSavedSettings) + SetWindowHiddendAndSkipItemsForCurrentFrame(). - IM_UNUSED(ret); - } + // Activate drag and drop + if (!g.DragDropActive) + { + IM_ASSERT(source_id != 0); + ClearDragDrop(); + IMGUI_DEBUG_LOG_ACTIVEID("[dragdrop] BeginDragDropSource() DragDropActive = true, source_id = %08X\n", source_id); + ImGuiPayload& payload = g.DragDropPayload; + payload.SourceId = source_id; + payload.SourceParentId = source_parent_id; + g.DragDropActive = true; + g.DragDropSourceFlags = flags; + g.DragDropMouseButton = mouse_button; + if (payload.SourceId == g.ActiveId) + g.ActiveIdNoClearOnFocusLoss = true; + } + g.DragDropSourceFrameCount = g.FrameCount; + g.DragDropWithinSource = true; + + if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit) + // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents. + bool ret; + if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip)) + ret = BeginTooltipHidden(); + else + ret = BeginTooltip(); + IM_ASSERT(ret); // FIXME-NEWBEGIN: If this ever becomes false, we need to Begin("##Hidden", NULL, ImGuiWindowFlags_NoSavedSettings) + SetWindowHiddendAndSkipItemsForCurrentFrame(). + IM_UNUSED(ret); + } - if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) - g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect; + if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) + g.LastItemData.StatusFlags &= ~ImGuiItemStatusFlags_HoveredRect; - return true; - } - return false; + return true; } void ImGui::EndDragDropSource() @@ -13034,7 +13352,7 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) if (window->SkipItems) return false; - IM_ASSERT(g.DragDropWithinTarget == false); + IM_ASSERT(g.DragDropWithinTarget == false && g.DragDropWithinSource == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget() g.DragDropTargetRect = bb; g.DragDropTargetClipRect = window->ClipRect; // May want to be overriden by user depending on use case? g.DragDropTargetId = id; @@ -13069,7 +13387,7 @@ bool ImGui::BeginDragDropTarget() if (g.DragDropPayload.SourceId == id) return false; - IM_ASSERT(g.DragDropWithinTarget == false); + IM_ASSERT(g.DragDropWithinTarget == false && g.DragDropWithinSource == false); // Can't nest BeginDragDropSource() and BeginDragDropTarget() g.DragDropTargetRect = display_rect; g.DragDropTargetClipRect = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect : window->ClipRect; g.DragDropTargetId = id; @@ -13266,7 +13584,7 @@ void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth) IM_ASSERT(g.LogEnabled == false); IM_ASSERT(g.LogFile == NULL); IM_ASSERT(g.LogBuffer.empty()); - g.LogEnabled = true; + g.LogEnabled = g.ItemUnclipByLog = true; g.LogType = type; g.LogNextPrefix = g.LogNextSuffix = NULL; g.LogDepthRef = window->DC.TreeDepth; @@ -13365,7 +13683,7 @@ void ImGui::LogFinish() break; } - g.LogEnabled = false; + g.LogEnabled = g.ItemUnclipByLog = false; g.LogType = ImGuiLogType_None; g.LogFile = NULL; g.LogBuffer.clear(); @@ -14456,9 +14774,9 @@ void ImGui::ShowMetricsWindow(bool* p_open) { // As it's difficult to interact with tree nodes while popups are open, we display everything inline. ImGuiWindow* window = popup_data.Window; - BulletText("PopupID: %08x, Window: '%s' (%s%s), BackupNavWindow '%s', ParentWindow '%s'", + BulletText("PopupID: %08x, Window: '%s' (%s%s), RestoreNavWindow '%s', ParentWindow '%s'", popup_data.PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? "Child;" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? "Menu;" : "", - popup_data.BackupNavWindow ? popup_data.BackupNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL"); + popup_data.RestoreNavWindow ? popup_data.RestoreNavWindow->Name : "NULL", window && window->ParentWindow ? window->ParentWindow->Name : "NULL"); } TreePop(); } @@ -14637,7 +14955,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) for (ImGuiKey key = ImGuiKey_NamedKey_BEGIN; key < ImGuiKey_NamedKey_END; key = (ImGuiKey)(key + 1)) { ImGuiKeyOwnerData* owner_data = GetKeyOwnerData(&g, key); - if (owner_data->OwnerCurr == ImGuiKeyOwner_None) + if (owner_data->OwnerCurr == ImGuiKeyOwner_NoOwner) continue; Text("%s: 0x%08X%s", GetKeyName(key), owner_data->OwnerCurr, owner_data->LockUntilRelease ? " LockUntilRelease" : owner_data->LockThisFrame ? " LockThisFrame" : ""); @@ -15097,7 +15415,7 @@ void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) { if (!TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) return; - for (const ImGuiStorage::ImGuiStoragePair& p : storage->Data) + for (const ImGuiStoragePair& p : storage->Data) BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer. TreePop(); } @@ -15291,8 +15609,11 @@ void ImGui::DebugLogV(const char* fmt, va_list args) if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTTY) IMGUI_DEBUG_PRINTF("%s", g.DebugLogBuf.begin() + old_size); #ifdef IMGUI_ENABLE_TEST_ENGINE + // IMGUI_TEST_ENGINE_LOG() adds a trailing \n automatically + const int new_size = g.DebugLogBuf.size(); + const bool trailing_carriage_return = (g.DebugLogBuf[new_size - 1] == '\n'); if (g.DebugLogFlags & ImGuiDebugLogFlags_OutputToTestEngine) - IMGUI_TEST_ENGINE_LOG("%s", g.DebugLogBuf.begin() + old_size); + IMGUI_TEST_ENGINE_LOG("%.*s", new_size - old_size - (trailing_carriage_return ? 1 : 0), g.DebugLogBuf.begin() + old_size); #endif } @@ -15360,25 +15681,7 @@ void ImGui::ShowDebugLogWindow(bool* p_open) clipper.Begin(g.DebugLogIndex.size()); while (clipper.Step()) for (int line_no = clipper.DisplayStart; line_no < clipper.DisplayEnd; line_no++) - { - const char* line_begin = g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no); - const char* line_end = g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no); - TextUnformatted(line_begin, line_end); // Display line - ImRect text_rect = g.LastItemData.Rect; - if (IsItemHovered()) - for (const char* p = line_begin; p <= line_end - 10; p++) // Search for 0x???????? identifiers - { - ImGuiID id = 0; - if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1) - continue; - ImVec2 p0 = CalcTextSize(line_begin, p); - ImVec2 p1 = CalcTextSize(p, p + 10); - g.LastItemData.Rect = ImRect(text_rect.Min + ImVec2(p0.x, 0.0f), text_rect.Min + ImVec2(p0.x + p1.x, p1.y)); - if (IsMouseHoveringRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, true)) - DebugLocateItemOnHover(id); - p += 10; - } - } + DebugTextUnformattedWithLocateItem(g.DebugLogIndex.get_line_begin(g.DebugLogBuf.c_str(), line_no), g.DebugLogIndex.get_line_end(g.DebugLogBuf.c_str(), line_no)); g.DebugLogFlags = backup_log_flags; if (GetScrollY() >= GetScrollMaxY()) SetScrollHereY(1.0f); @@ -15387,6 +15690,28 @@ void ImGui::ShowDebugLogWindow(bool* p_open) End(); } +// Display line, search for 0xXXXXXXXX identifiers and call DebugLocateItemOnHover() when hovered. +void ImGui::DebugTextUnformattedWithLocateItem(const char* line_begin, const char* line_end) +{ + TextUnformatted(line_begin, line_end); + if (!IsItemHovered()) + return; + ImGuiContext& g = *GImGui; + ImRect text_rect = g.LastItemData.Rect; + for (const char* p = line_begin; p <= line_end - 10; p++) + { + ImGuiID id = 0; + if (p[0] != '0' || (p[1] != 'x' && p[1] != 'X') || sscanf(p + 2, "%X", &id) != 1) + continue; + ImVec2 p0 = CalcTextSize(line_begin, p); + ImVec2 p1 = CalcTextSize(p, p + 10); + g.LastItemData.Rect = ImRect(text_rect.Min + ImVec2(p0.x, 0.0f), text_rect.Min + ImVec2(p0.x + p1.x, p1.y)); + if (IsMouseHoveringRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, true)) + DebugLocateItemOnHover(id); + p += 10; + } +} + //----------------------------------------------------------------------------- // [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, ID STACK TOOL) //----------------------------------------------------------------------------- @@ -15644,7 +15969,7 @@ void ImGui::ShowIDStackToolWindow(bool* p_open) Checkbox("Ctrl+C: copy path to clipboard", &tool->CopyToClipboardOnCtrlC); SameLine(); TextColored((time_since_copy >= 0.0f && time_since_copy < 0.75f && ImFmod(time_since_copy, 0.25f) < 0.25f * 0.5f) ? ImVec4(1.f, 1.f, 0.3f, 1.f) : ImVec4(), "*COPIED*"); - if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, ImGuiInputFlags_RouteGlobal)) + if (tool->CopyToClipboardOnCtrlC && Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteOverFocused)) { tool->CopyToClipboardLastTime = (float)g.Time; char* p = g.TempBuffer.Data; diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui.h b/libs/bgfx/3rdparty/dear-imgui/imgui.h index 386fb58..c48fd4c 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui.h +++ b/libs/bgfx/3rdparty/dear-imgui/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (headers) // Help: @@ -7,15 +7,19 @@ // - Read top of imgui.cpp for more details, links and comments. // Resources: -// - FAQ https://dearimgui.com/faq -// - Getting Started https://dearimgui.com/getting-started -// - Homepage https://github.com/ocornut/imgui -// - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/6897 (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 -// - Tests & Automation https://github.com/ocornut/imgui_test_engine +// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md) +// - Homepage ................... https://github.com/ocornut/imgui +// - Releases & changelog ....... https://github.com/ocornut/imgui/releases +// - Gallery .................... https://github.com/ocornut/imgui/issues/7503 (please post your screenshots/video there!) +// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there) +// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code) +// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more) +// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines) +// - Glossary https://github.com/ocornut/imgui/wiki/Glossary +// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools +// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui +// - Issues & support ........... https://github.com/ocornut/imgui/issues +// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps) // For first-time users having issues compiling/linking/running/loading fonts: // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. @@ -23,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.4" -#define IMGUI_VERSION_NUM 19040 +#define IMGUI_VERSION "1.90.9 WIP" +#define IMGUI_VERSION_NUM 19081 #define IMGUI_HAS_TABLE /* @@ -86,6 +90,8 @@ Index of this file: #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. + +// Check that version and structures layouts are matching between compiled imgui code and caller. Read comments above DebugCheckVersionAndDataLayout() for details. #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. @@ -126,6 +132,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind @@ -136,6 +143,17 @@ Index of this file: // [SECTION] Forward declarations and basic 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 +typedef unsigned short ImU16; // 16-bit unsigned integer +typedef signed int ImS32; // 32-bit signed integer == int +typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) +typedef signed long long ImS64; // 64-bit signed integer +typedef unsigned long long ImU64; // 64-bit unsigned integer + // Forward declarations struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit() struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback) @@ -160,7 +178,8 @@ struct ImGuiOnceUponAFrame; // Helper for running a block of code not mo struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiPlatformImeData; // Platform IME data for io.SetPlatformImeDataFn() function. struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use) -struct ImGuiStorage; // Helper for key->value storage +struct ImGuiStorage; // Helper for key->value storage (container sorted by key) +struct ImGuiStoragePair; // Helper for key->value storage (pair) struct ImGuiStyle; // Runtime data for styling/colors struct ImGuiTableSortSpecs; // Sorting specifications for a table (often handling sort specs for a single column, occasionally more) struct ImGuiTableColumnSortSpecs; // Sorting specification for one column of a table @@ -171,24 +190,26 @@ struct ImGuiViewport; // A Platform Window (always only one in 'ma // Enumerations // - We don't use strongly typed enums much because they add constraints (can't extend in private code, can't store typed in bit fields, extra casting on iteration) // - 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.GoToAll") 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. +// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments. +// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. +enum ImGuiDir : int; // -> enum ImGuiDir // Enum: A cardinal direction (Left, Right, Up, Down) enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value) enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen) +enum ImGuiSortDirection : ImU8; // -> enum ImGuiSortDirection // Enum: A sorting direction (ascending or descending) typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type -typedef int ImGuiDir; // -> enum ImGuiDir_ // Enum: A cardinal direction typedef int ImGuiMouseButton; // -> enum ImGuiMouseButton_ // Enum: A mouse button identifier (0=left, 1=right, 2=middle) typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A mouse cursor shape -typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending) typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor() // Flags (declared as int 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.GoToAll") 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. +// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments. +// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build @@ -201,6 +222,7 @@ typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: f typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for BeginDragDropSource(), AcceptDragDropPayload() typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. +typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for Shortcut(), SetNextItemShortcut() typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() typedef int ImGuiKeyChord; // -> ImGuiKey | ImGuiMod_XXX // Flags: for IsKeyChordPressed(), Shortcut() etc. an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values. typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() @@ -229,17 +251,6 @@ typedef void* ImTextureID; // Default: store a pointer or an integer fi typedef unsigned short ImDrawIdx; // Default: 16-bit (for maximum compatibility with renderer backends) #endif -// 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 -typedef unsigned short ImU16; // 16-bit unsigned integer -typedef signed int ImS32; // 32-bit signed integer == int -typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) -typedef signed long long ImS64; // 64-bit signed integer -typedef unsigned long long ImU64; // 64-bit unsigned integer - // 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 int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. @@ -690,7 +701,8 @@ namespace ImGui // Tooltips // - Tooltips are windows following the mouse. They do not take focus away. - // - A tooltip window can contain items of any types. SetTooltip() is a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom. + // - A tooltip window can contain items of any types. + // - SetTooltip() is more or less a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom (with a subtlety that it discard any previously submitted tooltip) IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true! IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip(). @@ -701,7 +713,7 @@ namespace ImGui // - SetItemTooltip() is a shortcut for the 'if (IsItemHovered(ImGuiHoveredFlags_ForTooltip)) { SetTooltip(...); }' idiom. // - Where 'ImGuiHoveredFlags_ForTooltip' itself is a shortcut to use 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' depending on active input type. For mouse it defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'. IMGUI_API bool BeginItemTooltip(); // begin/append a tooltip window if preceding item was hovered. - IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceeding item was hovered. override any previous call to SetTooltip(). + IMGUI_API void SetItemTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip if preceding item was hovered. override any previous call to SetTooltip(). IMGUI_API void SetItemTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); // Popups, Modals @@ -928,6 +940,24 @@ namespace ImGui IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call. + // Inputs Utilities: Shortcut Testing & Routing [BETA] + // - ImGuiKeyChord = a ImGuiKey + optional ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super. + // ImGuiKey_C // Accepted by functions taking ImGuiKey or ImGuiKeyChord arguments) + // ImGuiMod_Ctrl | ImGuiKey_C // Accepted by functions taking ImGuiKeyChord arguments) + // only ImGuiMod_XXX values are legal to combine with an ImGuiKey. You CANNOT combine two ImGuiKey values. + // - The general idea is that several callers may register interest in a shortcut, and only one owner gets it. + // Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut. + // Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts) + // Child2 -> no call // When Child2 is focused, Parent gets the shortcut. + // The whole system is order independent, so if Child1 makes its calls before Parent, results will be identical. + // This is an important property as it facilitate working with foreign code or larger codebase. + // - To understand the difference: + // - IsKeyChordPressed() compares mods and call IsKeyPressed() -> function has no side-effect. + // - Shortcut() submits a route, routes are resolved, if it currently can be routed it calls IsKeyChordPressed() -> function has (desirable) side-effects as it can prevents another call from getting the route. + // - Visualize registered routes in 'Metrics/Debugger->Inputs'. + IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0); + IMGUI_API void SetNextItemShortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags = 0); + // Inputs Utilities: Mouse specific // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. @@ -942,8 +972,8 @@ namespace ImGui IMGUI_API bool IsAnyMouseDown(); // [WILL OBSOLETE] is any mouse button held? This was designed for backends, but prefer having backend maintain a mask of held mouse buttons, because upcoming input queue system will make this invalid. IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve mouse position at the time of opening popup we have BeginPopup() into (helper to avoid user backing that value themselves) - IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) - IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (if lock_threshold < -1.0f, uses io.MouseDraggingThreshold) + IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold = -1.0f); // is mouse dragging? (uses io.MouseDraggingThreshold if lock_threshold < 0.0f) + IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button = 0, float lock_threshold = -1.0f); // return the delta from the initial clicking position while the mouse button is pressed or was just released. This is locked and return 0.0f until the mouse moves past a distance threshold at least once (uses io.MouseDraggingThreshold if lock_threshold < 0.0f) IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button = 0); // IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired mouse cursor shape. Important: reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired mouse cursor shape @@ -1053,28 +1083,37 @@ enum ImGuiChildFlags_ // (Those are per-item flags. There are shared flags in ImGuiIO: io.ConfigInputTextCursorBlink and io.ConfigInputTextEnterKeepActive) enum ImGuiInputTextFlags_ { + // Basic filters (also see ImGuiInputTextFlags_CallbackCharFilter) ImGuiInputTextFlags_None = 0, ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef - ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z - ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs - ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus - ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. - ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Callback on pressing TAB (for completion handling) - ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Callback on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Callback on each iteration. User code may query cursor position, modify text buffer. - ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. - ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field - ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). - ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally - ImGuiInputTextFlags_AlwaysOverwrite = 1 << 13, // Overwrite mode - ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode - ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_CharsScientific = 1 << 2, // Allow 0123456789.+-*/eE (Scientific notation input) + ImGuiInputTextFlags_CharsUppercase = 1 << 3, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 4, // Filter out spaces, tabs + + // Inputs + ImGuiInputTextFlags_AllowTabInput = 1 << 5, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 6, // Return 'true' when Enter is pressed (as opposed to every time the value was modified). Consider looking at the IsItemDeactivatedAfterEdit() function. + ImGuiInputTextFlags_EscapeClearsAll = 1 << 7, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 8, // In multi-line mode, validate with Enter, add new line with Ctrl+Enter (default is opposite: validate with Ctrl+Enter, add line with Enter). + + // Other options + ImGuiInputTextFlags_ReadOnly = 1 << 9, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 10, // Password mode, display all characters as '*', disable copy + ImGuiInputTextFlags_AlwaysOverwrite = 1 << 11, // Overwrite mode + ImGuiInputTextFlags_AutoSelectAll = 1 << 12, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_ParseEmptyRefVal = 1 << 13, // InputFloat(), InputInt(), InputScalar() etc. only: parse empty string as zero value. + ImGuiInputTextFlags_DisplayEmptyRefVal = 1 << 14, // InputFloat(), InputInt(), InputScalar() etc. only: when value is zero, do not display it. Generally used with ImGuiInputTextFlags_ParseEmptyRefVal. + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 15, // Disable following the cursor horizontally ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). - ImGuiInputTextFlags_CharsScientific = 1 << 17, // Allow 0123456789.+-*/eE (Scientific notation input) - ImGuiInputTextFlags_CallbackResize = 1 << 18, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) - ImGuiInputTextFlags_CallbackEdit = 1 << 19, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) - ImGuiInputTextFlags_EscapeClearsAll = 1 << 20, // Escape key clears content if not empty, and deactivate otherwise (contrast to default behavior of Escape to revert) + + // Callback features + ImGuiInputTextFlags_CallbackCompletion = 1 << 17, // Callback on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 18, // Callback on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 19, // Callback on each iteration. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 20, // Callback on character inputs to replace or discard them. Modify 'EventChar' to replace or discard, or return 1 in callback to discard. + ImGuiInputTextFlags_CallbackResize = 1 << 21, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this) + ImGuiInputTextFlags_CallbackEdit = 1 << 22, // Callback on any edit (note that InputText() already returns true on edit, the callback is useful mainly to manipulate the underlying buffer while focus is active) // Obsolete names //ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior @@ -1094,12 +1133,13 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow. IMPORTANT: node can still be marked open/close if you don't set the _Leaf flag! - ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). - ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line. In the future we may refactor the hit system to be front-to-back, allowing natural overlaps and then this can become the default. - ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (bypass the indented area). - ImGuiTreeNodeFlags_SpanAllColumns = 1 << 13, // Frame will span all columns of its container table (text will still fit in current column) - ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 14, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) - //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 15, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding() before the node. + ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode. + ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area). + ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text. + ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (text will still fit in current column) + ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 15, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 16, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog, #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS @@ -1284,7 +1324,7 @@ enum ImGuiDataType_ }; // A cardinal direction -enum ImGuiDir_ +enum ImGuiDir : int { ImGuiDir_None = -1, ImGuiDir_Left = 0, @@ -1295,7 +1335,7 @@ enum ImGuiDir_ }; // A sorting direction -enum ImGuiSortDirection_ +enum ImGuiSortDirection : ImU8 { ImGuiSortDirection_None = 0, ImGuiSortDirection_Ascending = 1, // Ascending = 0->9, A->Z etc. @@ -1414,13 +1454,13 @@ enum ImGuiKey : int // - In theory the value of keyboard modifiers should be roughly equivalent to a logical or of the equivalent left/right keys. // In practice: it's complicated; mods are often provided from different sources. Keyboard layout, IME, sticky keys and // backends tend to interfere and break that equivalence. The safer decision is to relay that ambiguity down to the end-user... + // - On macOS, we swap Cmd(Super) and Ctrl keys at the time of the io.AddKeyEvent() call. ImGuiMod_None = 0, - ImGuiMod_Ctrl = 1 << 12, // Ctrl + ImGuiMod_Ctrl = 1 << 12, // Ctrl (non-macOS), Cmd (macOS) ImGuiMod_Shift = 1 << 13, // Shift ImGuiMod_Alt = 1 << 14, // Option/Menu - ImGuiMod_Super = 1 << 15, // Cmd/Super/Windows - ImGuiMod_Shortcut = 1 << 11, // Alias for Ctrl (non-macOS) _or_ Super (macOS). - ImGuiMod_Mask_ = 0xF800, // 5-bits + ImGuiMod_Super = 1 << 15, // Windows/Super (non-macOS), Ctrl (macOS) + ImGuiMod_Mask_ = 0xF000, // 4-bits // [Internal] Prior to 1.87 we required user to fill io.KeysDown[512] using their own native index + the io.KeyMap[] array. // We are ditching this method but keeping a legacy path for user code doing e.g. IsKeyPressed(MY_NATIVE_KEY_CODE) @@ -1437,11 +1477,37 @@ enum ImGuiKey : int #endif #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89 //ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87 #endif }; +// Flags for Shortcut(), SetNextItemShortcut(), +// (and for upcoming extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() that are still in imgui_internal.h) +// Don't mistake with ImGuiInputTextFlags! (which is for ImGui::InputText() function) +enum ImGuiInputFlags_ +{ + ImGuiInputFlags_None = 0, + ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. + + // Flags for Shortcut(), SetNextItemShortcut() + // - Routing policies: RouteGlobal+OverActive >> RouteActive or RouteFocused (if owner is active item) >> RouteGlobal+OverFocused >> RouteFocused (if in focused window stack) >> RouteGlobal. + // - Default policy is RouteFocused. Can select only 1 policy among all available. + ImGuiInputFlags_RouteActive = 1 << 10, // Route to active item only. + ImGuiInputFlags_RouteFocused = 1 << 11, // Route to windows in the focus stack (DEFAULT). Deep-most focused window takes inputs. Active item takes inputs over deep-most focused window. + ImGuiInputFlags_RouteGlobal = 1 << 12, // Global route (unless a focused window or active item registered the route). + ImGuiInputFlags_RouteAlways = 1 << 13, // Do not register route, poll keys directly. + // - Routing options + ImGuiInputFlags_RouteOverFocused = 1 << 14, // Option: global route: higher priority than focused route (unless active item in focused route). + ImGuiInputFlags_RouteOverActive = 1 << 15, // Option: global route: higher priority than active item. Unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this. May not be fully honored as user/internal code is likely to always assume they can access keys when active. + ImGuiInputFlags_RouteUnlessBgFocused = 1 << 16, // Option: global route: will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + ImGuiInputFlags_RouteFromRootWindow = 1 << 17, // Option: route evaluated from the point of view of root window rather than current window. + + // Flags for SetNextItemShortcut() + ImGuiInputFlags_Tooltip = 1 << 18, // Automatically display a tooltip when hovering item [BETA] Unsure of right api (opt-in/opt-out) +}; + #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO // OBSOLETED in 1.88 (from July 2022): ImGuiNavInput and io.NavInputs[]. // Official backends between 1.60 and 1.86: will keep working and feed gamepad inputs as long as IMGUI_DISABLE_OBSOLETE_KEYIO is not set. @@ -1543,41 +1609,45 @@ enum ImGuiCol_ // - The enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. // During initialization or between frames, feel free to just poke into ImGuiStyle directly. // - Tip: Use your programming IDE navigation facilities on the names in the _second column_ below to find the actual members and their description. -// In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") 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. +// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments. +// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. // - When changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. 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 - ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize - ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign - ImGuiStyleVar_ChildRounding, // float ChildRounding - ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize - ImGuiStyleVar_PopupRounding, // float PopupRounding - ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize - ImGuiStyleVar_FramePadding, // ImVec2 FramePadding - ImGuiStyleVar_FrameRounding, // float FrameRounding - ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize - ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing - ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing - ImGuiStyleVar_IndentSpacing, // float IndentSpacing - ImGuiStyleVar_CellPadding, // ImVec2 CellPadding - ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize - ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding - ImGuiStyleVar_GrabMinSize, // float GrabMinSize - ImGuiStyleVar_GrabRounding, // float GrabRounding - ImGuiStyleVar_TabRounding, // float TabRounding - ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize - ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign - ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign - ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize - ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign - ImGuiStyleVar_SeparatorTextPadding,// ImVec2 SeparatorTextPadding + // 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 + ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize + ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign + ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize + ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize + ImGuiStyleVar_FramePadding, // ImVec2 FramePadding + ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize + ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing + ImGuiStyleVar_IndentSpacing, // float IndentSpacing + ImGuiStyleVar_CellPadding, // ImVec2 CellPadding + ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize + ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding + ImGuiStyleVar_GrabMinSize, // float GrabMinSize + ImGuiStyleVar_GrabRounding, // float GrabRounding + ImGuiStyleVar_TabRounding, // float TabRounding + ImGuiStyleVar_TabBorderSize, // float TabBorderSize + ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize + ImGuiStyleVar_TableAngledHeadersAngle, // float TableAngledHeadersAngle + ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign + ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign + ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign + ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize + ImGuiStyleVar_SeparatorTextAlign, // ImVec2 SeparatorTextAlign + ImGuiStyleVar_SeparatorTextPadding, // ImVec2 SeparatorTextPadding ImGuiStyleVar_COUNT }; @@ -1588,10 +1658,8 @@ enum ImGuiButtonFlags_ ImGuiButtonFlags_MouseButtonLeft = 1 << 0, // React on left mouse button (default) ImGuiButtonFlags_MouseButtonRight = 1 << 1, // React on right mouse button ImGuiButtonFlags_MouseButtonMiddle = 1 << 2, // React on center mouse button - - // [Internal] - ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, - ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, + ImGuiButtonFlags_MouseButtonMask_ = ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_MouseButtonRight | ImGuiButtonFlags_MouseButtonMiddle, // [Internal] + //ImGuiButtonFlags_MouseButtonDefault_ = ImGuiButtonFlags_MouseButtonLeft, }; // Flags for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() @@ -1864,7 +1932,7 @@ struct ImGuiTableColumnSortSpecs ImGuiID ColumnUserID; // User id of the column (if specified by a TableSetupColumn() call) ImS16 ColumnIndex; // Index of the column ImS16 SortOrder; // Index within parent ImGuiTableSortSpecs (always stored in order starting from 0, tables sorted on a single criteria will always have a 0 here) - ImGuiSortDirection SortDirection : 8; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending + ImGuiSortDirection SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending ImGuiTableColumnSortSpecs() { memset(this, 0, sizeof(*this)); } }; @@ -1992,7 +2060,7 @@ struct ImGuiStyle float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines. ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label). - ImVec2 CellPadding; // Padding within a table cell. CellPadding.y may be altered between different rows. + ImVec2 CellPadding; // Padding within a table cell. Cellpadding.x is locked for entire table. CellPadding.y may be altered between different rows. ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1). @@ -2006,15 +2074,16 @@ struct ImGuiStyle float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees). + ImVec2 TableAngledHeadersTextAlign;// Alignment of angled headers within the cell ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. float SeparatorTextBorderSize; // Thickkness of border in SeparatorText() ImVec2 SeparatorTextAlign; // Alignment of text within the separator. Defaults to (0.0f, 0.5f) (left aligned, center). ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y. - ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. - ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly! - float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen. + ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured). + float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later. bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList). bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList). @@ -2039,6 +2108,9 @@ struct ImGuiStyle //----------------------------------------------------------------------------- // Communicate most settings and inputs/outputs to Dear ImGui using this structure. // Access via ImGui::GetIO(). Read 'Programmer guide' section in .cpp file for general usage. +// It is generally expected that: +// - initialization: backends and user code writes to ImGuiIO. +// - main loop: backends writes to ImGuiIO, user code and imgui code reads from ImGuiIO. //----------------------------------------------------------------------------- // [Internal] Storage used by IsKeyDown(), IsKeyPressed() etc functions. @@ -2074,7 +2146,7 @@ struct ImGuiIO // Miscellaneous options bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. - bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. + bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). @@ -2185,16 +2257,6 @@ struct ImGuiIO int MetricsActiveWindows; // Number of active windows ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. - // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. - // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). - // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. - bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. - float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. - //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. -#endif - //------------------------------------------------------------------ // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! //------------------------------------------------------------------ @@ -2215,7 +2277,7 @@ struct ImGuiIO bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows // Other state maintained from data above + IO function calls - ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. DOES NOT CONTAINS ImGuiMod_Shortcut which is pretranslated). Read-only, updated by NewFrame() + ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame() ImGuiKeyData KeysData[ImGuiKey_KeysData_SIZE]; // Key state for all known keys. Use IsKeyXXX() functions to access this. bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup. ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid) @@ -2229,6 +2291,7 @@ struct ImGuiIO 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 MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system. + bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a ctrl-click that spawned a simulated right 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 float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds) @@ -2240,6 +2303,16 @@ struct ImGuiIO ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. + // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. + // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). + // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. + bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. + float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. + //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. +#endif + IMGUI_API ImGuiIO(); }; @@ -2264,6 +2337,8 @@ struct ImGuiInputTextCallbackData void* UserData; // What user passed to InputText() // Read-only // Arguments for the different callback events + // - During Resize callback, Buf will be same as your input buffer. + // - However, during Completion/History/Always callback, Buf always points to our own internal data (it is not the same as your buffer)! Changes to it will be reflected into your own buffer shortly after the callback. // - To modify the text buffer in a callback, prefer using the InsertChars() / DeleteChars() function. InsertChars() will take care of calling the resize callback if necessary. // - If you know your edits are not going to resize the underlying buffer allocation, you may modify the contents of 'Buf[]' directly. You need to update 'BufTextLen' accordingly (0 <= BufTextLen < BufSize) and set 'BufDirty'' to true so InputText can update its internal state. ImWchar EventChar; // Character input // Read-write // [CharFilter] Replace character with another one, or set to zero to drop. return 1 is equivalent to setting EventChar=0; @@ -2386,6 +2461,16 @@ struct ImGuiTextBuffer IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); }; +// [Internal] Key+Value for ImGuiStorage +struct ImGuiStoragePair +{ + ImGuiID key; + union { int val_i; float val_f; void* val_p; }; + ImGuiStoragePair(ImGuiID _key, int _val) { key = _key; val_i = _val; } + ImGuiStoragePair(ImGuiID _key, float _val) { key = _key; val_f = _val; } + ImGuiStoragePair(ImGuiID _key, void* _val) { key = _key; val_p = _val; } +}; + // Helper: Key->Value storage // Typically you don't have to worry about this since a storage is held within each Window. // We use it to e.g. store collapse state for a tree (Int 0/1) @@ -2397,15 +2482,6 @@ struct ImGuiTextBuffer struct ImGuiStorage { // [Internal] - struct ImGuiStoragePair - { - ImGuiID key; - union { int val_i; float val_f; void* val_p; }; - ImGuiStoragePair(ImGuiID _key, int _val) { key = _key; val_i = _val; } - ImGuiStoragePair(ImGuiID _key, float _val) { key = _key; val_f = _val; } - ImGuiStoragePair(ImGuiID _key, void* _val) { key = _key; val_p = _val; } - }; - ImVector Data; // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) @@ -2434,6 +2510,10 @@ struct ImGuiStorage IMGUI_API void BuildSortByKey(); // Obsolete: use on your own storage if you know only integer are being stored (open/close all tree nodes) IMGUI_API void SetAllInt(int val); + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + //typedef ::ImGuiStoragePair ImGuiStoragePair; // 1.90.8: moved type outside struct +#endif }; // Helper: Manually clip large list of items. @@ -2707,15 +2787,15 @@ struct ImDrawList // [Internal, used while building lists] unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0. ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) - const char* _OwnerName; // Pointer to owner window's name for debugging ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) - ImVector _ClipRectStack; // [Internal] - ImVector _TextureIdStack; // [Internal] ImVector _Path; // [Internal] current path building ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back(). ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) + ImVector _ClipRectStack; // [Internal] + ImVector _TextureIdStack; // [Internal] float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content + const char* _OwnerName; // Pointer to owner window's name for debugging // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) ImDrawList(ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; } @@ -2748,15 +2828,20 @@ struct ImDrawList IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0); IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f); IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments); - IMGUI_API void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f); - IMGUI_API void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0); + IMGUI_API void AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f); + IMGUI_API void AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot = 0.0f, int num_segments = 0); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); - IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); IMGUI_API void AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Cubic Bezier (4 control points) IMGUI_API void AddBezierQuadratic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, ImU32 col, float thickness, int num_segments = 0); // Quadratic Bezier (3 control points) + // General polygon + // - Only simple polygons are supported by filling functions (no self-intersections, no holes). + // - Concave polygon fill is more expensive than convex one: it has O(N^2) complexity. Provided as a convenience fo user but not used by main library. + IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, ImDrawFlags flags, float thickness); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); + IMGUI_API void AddConcavePolyFilled(const ImVec2* points, int num_points, ImU32 col); + // Image primitives // - Read FAQ to understand what ImTextureID is. // - "p_min" and "p_max" represent the upper-left and lower-right corners of the rectangle. @@ -2772,10 +2857,11 @@ struct ImDrawList inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path.Data[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); } inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } + inline void PathFillConcave(ImU32 col) { AddConcavePolyFilled(_Path.Data, _Path.Size, col); _Path.Size = 0; } inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; } IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0); IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle - IMGUI_API void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse + IMGUI_API void PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points) IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points) IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0); @@ -2808,6 +2894,9 @@ struct ImDrawList inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } // Write vertex with unique index // Obsolete names + //inline void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024) + //inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) + //inline void PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0) { PathEllipticalArcTo(center, ImVec2(radius_x, radius_y), rot, a_min, a_max, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024) //inline void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0) { AddBezierCubic(p1, p2, p3, p4, col, thickness, num_segments); } // OBSOLETED in 1.80 (Jan 2021) //inline void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0) { PathBezierCubicCurveTo(p2, p3, p4, num_segments); } // OBSOLETED in 1.80 (Jan 2021) @@ -2996,7 +3085,7 @@ struct ImFontAtlas // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. // - After calling Build(), you can query the rectangle position and render your pixels. - // - If you render colored output, set 'atlas->TexPixelsUseColors = true' as this may help some backends decide of prefered texture format. + // - If you render colored output, set 'atlas->TexPixelsUseColors = true' as this may help some backends decide of preferred texture format. // - You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), // so you can render e.g. custom colorful icons and use them as regular glyphs. // - Read docs/FONTS.md for more details about using colorful icons. @@ -3162,15 +3251,6 @@ struct ImGuiPlatformImeData // Please keep your copy of dear imgui up to date! Occasionally set '#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS' in imconfig.h to stay ahead. //----------------------------------------------------------------------------- -namespace ImGui -{ -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // map ImGuiKey_* values into legacy native key index. == io.KeyMap[key] -#else - static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END && "ImGuiKey and native_index was merged together and native_index is disabled by IMGUI_DISABLE_OBSOLETE_KEYIO. Please switch to ImGuiKey."); return key; } -#endif -} - #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { @@ -3189,11 +3269,14 @@ namespace ImGui static inline void PopAllowKeyboardFocus() { PopTabStop(); } // OBSOLETED in 1.89 (from August 2022) IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // Use new ImageButton() signature (explicit item id, regular FramePadding) - // OBSOLETED in 1.88 (from May 2022) - static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value. - static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value. + // OBSOLETED in 1.87 (from February 2022 but more formally obsoleted April 2024) + IMGUI_API ImGuiKey GetKeyIndex(ImGuiKey key); // Map ImGuiKey_* values into legacy native key index. == io.KeyMap[key]. When using a 1.87+ backend using io.AddKeyEvent(), calling GetKeyIndex() with ANY ImGuiKey_XXXX values will return the same value! + //static inline ImGuiKey GetKeyIndex(ImGuiKey key) { IM_ASSERT(key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END); return key; } // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) + //-- OBSOLETED in 1.88 (from May 2022) + //static inline void CaptureKeyboardFromApp(bool want_capture_keyboard = true) { SetNextFrameWantCaptureKeyboard(want_capture_keyboard); } // Renamed as name was misleading + removed default value. + //static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value. //-- OBSOLETED in 1.86 (from November 2021) //IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Code removed, see 1.90 for last version of the code. Calculate range of visible items for large list of evenly sized items. Prefer using ImGuiListClipper. //-- OBSOLETED in 1.85 (from August 2021) diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_demo.cpp b/libs/bgfx/3rdparty/dear-imgui/imgui_demo.cpp index 707c14d..b2f0f4a 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_demo.cpp +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (demo code) // Help: @@ -7,9 +7,14 @@ // - Need help integrating Dear ImGui in your codebase? // - Read Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started // - Read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. -// Read imgui.cpp for more details, documentation and comments. +// Read top of imgui.cpp and imgui.h for many details, documentation, comments, links. // Get the latest version at https://github.com/ocornut/imgui +// How to easily locate code? +// - Use the Item Picker to debug break in code by clicking any widgets: https://github.com/ocornut/imgui/wiki/Debug-Tools +// - Browse an online version the demo with code linked to hovered widgets: https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html +// - Find a visible string and search for it in the code! + //--------------------------------------------------- // PLEASE DO NOT REMOVE THIS FILE FROM YOUR PROJECT! //--------------------------------------------------- @@ -54,8 +59,9 @@ // Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp. // Navigating this file: -// - In Visual Studio: CTRL+comma ("Edit.GoToAll") 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. +// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments. +// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. /* @@ -130,6 +136,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning: macro name is a reserved identifier #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size @@ -259,6 +266,9 @@ void ImGui::ShowDemoWindow(bool* p_open) // Most functions would normally just assert/crash if the context is missing. IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing Dear ImGui context. Refer to examples app!"); + // Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues. + IMGUI_CHECKVERSION(); + // Examples Apps (accessible from the "Examples" menu) static bool show_app_main_menu_bar = false; static bool show_app_console = false; @@ -481,6 +491,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback."); ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly); ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors); + ImGui::SameLine(); HelpMarker("Swap Cmd<>Ctrl keys, enable various MacOS style behaviors."); ImGui::Text("Also see Style->Rendering for rendering options."); ImGui::SeparatorText("Debug"); @@ -899,13 +910,18 @@ static void ShowDemoWindowWidgets() if (i == 0) ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + // Here we use PushID() to generate a unique base ID, and then the "" used as TreeNode id won't conflict. + // An alternative to using 'PushID() + TreeNode("", ...)' to generate a unique ID is to use 'TreeNode((void*)(intptr_t)i, ...)', + // aka generate a dummy pointer-sized value to be hashed. The demo below uses that technique. Both are fine. + ImGui::PushID(i); + if (ImGui::TreeNode("", "Child %d", i)) { ImGui::Text("blah blah"); ImGui::SameLine(); if (ImGui::SmallButton("button")) {} ImGui::TreePop(); } + ImGui::PopID(); } ImGui::TreePop(); } @@ -923,7 +939,10 @@ static void ShowDemoWindowWidgets() ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)"); ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); ImGui::Text("Hello!"); @@ -956,6 +975,12 @@ static void ShowDemoWindowWidgets() ImGui::Text("This is a drag and drop source"); ImGui::EndDragDropSource(); } + if (i == 2) + { + // Item 2 has an additional inline button to help demonstrate SpanTextWidth. + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + } if (node_open) { ImGui::BulletText("Blah blah\nBlah Blah"); @@ -1288,6 +1313,7 @@ static void ShowDemoWindowWidgets() } ImGui::EndListBox(); } + ImGui::SameLine(); HelpMarker("Here we are sharing selection state between both boxes."); // Custom size: use all width, 5 items tall ImGui::Text("Full-width:"); @@ -1818,10 +1844,10 @@ static void ShowDemoWindowWidgets() ImGui::Checkbox("Animate", &animate); // Plot as lines and plot as histogram - IMGUI_DEMO_MARKER("Widgets/Plotting/PlotLines, PlotHistogram"); 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)); + //ImGui::SameLine(); HelpMarker("Consider using ImPlot instead!"); // 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 @@ -1871,15 +1897,17 @@ static void ShowDemoWindowWidgets() ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Progress Bars"); + if (ImGui::TreeNode("Progress Bars")) + { // Animate a simple progress bar - IMGUI_DEMO_MARKER("Widgets/Plotting/ProgressBar"); static float progress = 0.0f, progress_dir = 1.0f; - if (animate) - { - progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; - if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } - if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } - } + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. @@ -1891,6 +1919,13 @@ static void ShowDemoWindowWidgets() char buf[32]; sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + + // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value. + // Adjust the factor if you want to adjust the animation speed. + ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching.."); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Indeterminate"); + ImGui::TreePop(); } @@ -2238,20 +2273,24 @@ static void ShowDemoWindowWidgets() IMGUI_DEMO_MARKER("Widgets/Data Types/Inputs"); static bool inputs_step = true; + static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None; ImGui::SeparatorText("Inputs"); ImGui::Checkbox("Show step buttons", &inputs_step); - ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d"); - ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u"); - ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); - ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X"); - ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); - ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X"); - ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); - ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); - ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); - ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly); + ImGui::CheckboxFlags("ImGuiInputTextFlags_ParseEmptyRefVal", &flags, ImGuiInputTextFlags_ParseEmptyRefVal); + ImGui::CheckboxFlags("ImGuiInputTextFlags_DisplayEmptyRefVal", &flags, ImGuiInputTextFlags_DisplayEmptyRefVal); + ImGui::InputScalar("input s8", ImGuiDataType_S8, &s8_v, inputs_step ? &s8_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u8", ImGuiDataType_U8, &u8_v, inputs_step ? &u8_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s16", ImGuiDataType_S16, &s16_v, inputs_step ? &s16_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input u16", ImGuiDataType_U16, &u16_v, inputs_step ? &u16_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d", flags); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%04X", flags); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u", flags); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", flags); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL, NULL, NULL, flags); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL, NULL, NULL, flags); ImGui::TreePop(); } @@ -2481,9 +2520,7 @@ static void ShowDemoWindowWidgets() { IM_UNUSED(payload); ImGui::SetMouseCursor(ImGuiMouseCursor_NotAllowed); - ImGui::BeginTooltip(); - ImGui::Text("Cannot drop here!"); - ImGui::EndTooltip(); + ImGui::SetTooltip("Cannot drop here!"); } ImGui::EndDragDropTarget(); } @@ -3842,7 +3879,7 @@ static void ShowDemoWindowPopups() static int item = 1; static float color[4] = { 0.4f, 0.7f, 0.0f, 0.5f }; ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - ImGui::ColorEdit4("color", color); + ImGui::ColorEdit4("Color", color); if (ImGui::Button("Add another modal..")) ImGui::OpenPopup("Stacked 2"); @@ -3854,6 +3891,7 @@ static void ShowDemoWindowPopups() if (ImGui::BeginPopupModal("Stacked 2", &unused_open)) { ImGui::Text("Hello from Stacked The Second!"); + ImGui::ColorEdit4("Color", color); // Allow opening another nested popup if (ImGui::Button("Close")) ImGui::CloseCurrentPopup(); ImGui::EndPopup(); @@ -5139,7 +5177,8 @@ static void ShowDemoWindowTables() static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns; - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags, ImGuiTreeNodeFlags_SpanAllColumns); HelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns."); @@ -5328,6 +5367,17 @@ static void ShowDemoWindowTables() ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2); ImGui::CheckboxFlags("Disable header contributing to column width", &column_flags, ImGuiTableColumnFlags_NoHeaderWidth); + if (ImGui::TreeNode("Style settings")) + { + ImGui::SameLine(); + HelpMarker("Giving access to some ImGuiStyle value in this demo for convenience."); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::SliderAngle("style.TableAngledHeadersAngle", &ImGui::GetStyle().TableAngledHeadersAngle, -50.0f, +50.0f); + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8); + ImGui::SliderFloat2("style.TableAngledHeadersTextAlign", (float*)&ImGui::GetStyle().TableAngledHeadersTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::TreePop(); + } + if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12))) { ImGui::TableSetupColumn(column_names[0], ImGuiTableColumnFlags_NoHide | ImGuiTableColumnFlags_NoReorder); @@ -5479,6 +5529,7 @@ static void ShowDemoWindowTables() HelpMarker("Multiple tables with the same identifier will share their settings, width, visibility, order etc."); static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings; + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); ImGui::CheckboxFlags("ImGuiTableFlags_SizingFixedFit", &flags, ImGuiTableFlags_SizingFixedFit); ImGui::CheckboxFlags("ImGuiTableFlags_HighlightHoveredColumn", &flags, ImGuiTableFlags_HighlightHoveredColumn); @@ -6138,12 +6189,14 @@ static void ShowDemoWindowInputs() // Display inputs submitted to ImGuiIO IMGUI_DEMO_MARKER("Inputs & Focus/Inputs"); ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode("Inputs")) + bool inputs_opened = ImGui::TreeNode("Inputs"); + ImGui::SameLine(); + HelpMarker( + "This is a simplified view. See more detailed input state:\n" + "- in 'Tools->Metrics/Debugger->Inputs'.\n" + "- in 'Tools->Debug Log->IO'."); + if (inputs_opened) { - HelpMarker( - "This is a simplified view. See more detailed input state:\n" - "- in 'Tools->Metrics/Debugger->Inputs'.\n" - "- in 'Tools->Debug Log->IO'."); if (ImGui::IsMousePosValid()) ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); else @@ -6174,15 +6227,17 @@ static void ShowDemoWindowInputs() // Display ImGuiIO output flags IMGUI_DEMO_MARKER("Inputs & Focus/Outputs"); ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode("Outputs")) + bool outputs_opened = ImGui::TreeNode("Outputs"); + ImGui::SameLine(); + HelpMarker( + "The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui " + "to instruct your application of how to route inputs. Typically, when a value is true, it means " + "Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n" + "The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, " + "and underlying application should ignore mouse inputs (in practice there are many and more subtle " + "rules leading to how those flags are set)."); + if (outputs_opened) { - HelpMarker( - "The value of io.WantCaptureMouse and io.WantCaptureKeyboard are normally set by Dear ImGui " - "to instruct your application of how to route inputs. Typically, when a value is true, it means " - "Dear ImGui wants the corresponding inputs and we expect the underlying application to ignore them.\n\n" - "The most typical case is: when hovering a window, Dear ImGui set io.WantCaptureMouse to true, " - "and underlying application should ignore mouse inputs (in practice there are many and more subtle " - "rules leading to how those flags are set)."); ImGui::Text("io.WantCaptureMouse: %d", io.WantCaptureMouse); ImGui::Text("io.WantCaptureMouseUnlessPopupClose: %d", io.WantCaptureMouseUnlessPopupClose); ImGui::Text("io.WantCaptureKeyboard: %d", io.WantCaptureKeyboard); @@ -6216,6 +6271,102 @@ static void ShowDemoWindowInputs() ImGui::TreePop(); } + // Demonstrate using Shortcut() and Routing Policies. + // The general flow is: + // - Code interested in a chord (e.g. "Ctrl+A") declares their intent. + // - Multiple locations may be interested in same chord! Routing helps find a winner. + // - Every frame, we resolve all claims and assign one owner if the modifiers are matching. + // - The lower-level function is 'bool SetShortcutRouting()', returns true when caller got the route. + // - Most of the times, SetShortcutRouting() is not called directly. User mostly calls Shortcut() with routing flags. + // - If you call Shortcut() WITHOUT any routing option, it uses ImGuiInputFlags_RouteFocused. + // TL;DR: Most uses will simply be: + // - Shortcut(ImGuiMod_Ctrl | ImGuiKey_A); // Use ImGuiInputFlags_RouteFocused policy. + IMGUI_DEMO_MARKER("Inputs & Focus/Shortcuts"); + if (ImGui::TreeNode("Shortcuts")) + { + static ImGuiInputFlags route_options = ImGuiInputFlags_Repeat; + static ImGuiInputFlags route_type = ImGuiInputFlags_RouteFocused; + ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &route_options, ImGuiInputFlags_Repeat); + ImGui::RadioButton("ImGuiInputFlags_RouteActive", &route_type, ImGuiInputFlags_RouteActive); + ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &route_type, ImGuiInputFlags_RouteFocused); + ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &route_type, ImGuiInputFlags_RouteGlobal); + ImGui::Indent(); + ImGui::BeginDisabled(route_type != ImGuiInputFlags_RouteGlobal); + ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverFocused", &route_options, ImGuiInputFlags_RouteOverFocused); + ImGui::CheckboxFlags("ImGuiInputFlags_RouteOverActive", &route_options, ImGuiInputFlags_RouteOverActive); + ImGui::CheckboxFlags("ImGuiInputFlags_RouteUnlessBgFocused", &route_options, ImGuiInputFlags_RouteUnlessBgFocused); + ImGui::EndDisabled(); + ImGui::Unindent(); + ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &route_type, ImGuiInputFlags_RouteAlways); + ImGuiInputFlags flags = route_type | route_options; // Merged flags + if (route_type != ImGuiInputFlags_RouteGlobal) + flags &= ~(ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused); + + ImGui::SeparatorText("Using SetNextItemShortcut()"); + ImGui::Text("Ctrl+S"); + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, flags | ImGuiInputFlags_Tooltip); + ImGui::Button("Save"); + ImGui::Text("Alt+F"); + ImGui::SetNextItemShortcut(ImGuiMod_Alt | ImGuiKey_F, flags | ImGuiInputFlags_Tooltip); + static float f = 0.5f; + ImGui::SliderFloat("Factor", &f, 0.0f, 1.0f); + + ImGui::SeparatorText("Using Shortcut()"); + const float line_height = ImGui::GetTextLineHeightWithSpacing(); + const ImGuiKeyChord key_chord = ImGuiMod_Ctrl | ImGuiKey_A; + + ImGui::Text("Ctrl+A"); + ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "..."); + + ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 1.0f, 0.1f)); + + ImGui::BeginChild("WindowA", ImVec2(-FLT_MIN, line_height * 14), true); + ImGui::Text("Press CTRL+A and see who receives it!"); + ImGui::Separator(); + + // 1: Window polling for CTRL+A + ImGui::Text("(in WindowA)"); + ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "..."); + + // 2: InputText also polling for CTRL+A: it always uses _RouteFocused internally (gets priority when active) + // (Commmented because the owner-aware version of Shortcut() is still in imgui_internal.h) + //char str[16] = "Press CTRL+A"; + //ImGui::Spacing(); + //ImGui::InputText("InputTextB", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly); + //ImGuiID item_id = ImGui::GetItemID(); + //ImGui::SameLine(); HelpMarker("Internal widgets always use _RouteFocused"); + //ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags, item_id) ? "PRESSED" : "..."); + + // 3: Dummy child is not claiming the route: focusing them shouldn't steal route away from WindowA + ImGui::BeginChild("ChildD", ImVec2(-FLT_MIN, line_height * 4), true); + ImGui::Text("(in ChildD: not using same Shortcut)"); + ImGui::Text("IsWindowFocused: %d", ImGui::IsWindowFocused()); + ImGui::EndChild(); + + // 4: Child window polling for CTRL+A. It is deeper than WindowA and gets priority when focused. + ImGui::BeginChild("ChildE", ImVec2(-FLT_MIN, line_height * 4), true); + ImGui::Text("(in ChildE: using same Shortcut)"); + ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "..."); + ImGui::EndChild(); + + // 5: In a popup + if (ImGui::Button("Open Popup")) + ImGui::OpenPopup("PopupF"); + if (ImGui::BeginPopup("PopupF")) + { + ImGui::Text("(in PopupF)"); + ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "..."); + // (Commmented because the owner-aware version of Shortcut() is still in imgui_internal.h) + //ImGui::InputText("InputTextG", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly); + //ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags, ImGui::GetItemID()) ? "PRESSED" : "..."); + ImGui::EndPopup(); + } + ImGui::EndChild(); + ImGui::PopStyleColor(); + + ImGui::TreePop(); + } + // Display mouse cursors IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors"); if (ImGui::TreeNode("Mouse Cursors")) @@ -6351,7 +6502,7 @@ void ImGui::ShowAboutWindow(bool* p_open) ImGui::Separator(); ImGui::Text("By Omar Cornut and all Dear ImGui contributors."); ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); - ImGui::Text("If your company uses this, please consider sponsoring the project!"); + ImGui::Text("If your company uses this, please consider funding the project."); static bool show_config_info = false; ImGui::Checkbox("Config/Build Information", &show_config_info); @@ -6616,12 +6767,13 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SeparatorText("Tables"); ImGui::SliderFloat2("CellPadding", (float*)&style.CellPadding, 0.0f, 20.0f, "%.0f"); ImGui::SliderAngle("TableAngledHeadersAngle", &style.TableAngledHeadersAngle, -50.0f, +50.0f); + ImGui::SliderFloat2("TableAngledHeadersTextAlign", (float*)&style.TableAngledHeadersTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SeparatorText("Widgets"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); int window_menu_button_position = style.WindowMenuButtonPosition + 1; if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0")) - style.WindowMenuButtonPosition = window_menu_button_position - 1; + style.WindowMenuButtonPosition = (ImGuiDir)(window_menu_button_position - 1); ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0"); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content."); @@ -6646,7 +6798,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) } ImGui::SeparatorText("Misc"); - ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); + ImGui::SliderFloat2("DisplayWindowPadding", (float*)&style.DisplayWindowPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen."); + ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::SameLine(); HelpMarker("Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); ImGui::EndTabItem(); } @@ -7079,6 +7232,7 @@ struct ExampleAppConsole } // Options, Filter + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_O, ImGuiInputFlags_Tooltip); if (ImGui::Button("Options")) ImGui::OpenPopup("Options"); ImGui::SameLine(); @@ -7087,7 +7241,7 @@ struct ExampleAppConsole // Reserve enough left-over height for 1 separator + 1 input text const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); - if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar)) + if (ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), ImGuiChildFlags_None, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_NavFlattened)) { if (ImGui::BeginPopupContextWindow()) { @@ -7789,7 +7943,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open) if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Resize vertical + lock current width if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Resize horizontal + lock current height if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width Between and 400 and 500 - if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 500), ImVec2(-1, FLT_MAX)); // Height at least 400 + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, FLT_MAX)); // Height at least 400 if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::AspectRatio, (void*)&aspect_ratio); // Aspect ratio if (type == 7) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square if (type == 8) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)&fixed_step); // Fixed Step @@ -7964,6 +8118,14 @@ static void ShowExampleAppWindowTitles(bool*) // [SECTION] Example App: Custom Rendering using ImDrawList API / ShowExampleAppCustomRendering() //----------------------------------------------------------------------------- +// Add a |_| looking shape +static void PathConcaveShape(ImDrawList* draw_list, float x, float y, float sz) +{ + const ImVec2 pos_norms[] = { { 0.0f, 0.0f }, { 0.3f, 0.0f }, { 0.3f, 0.7f }, { 0.7f, 0.7f }, { 0.7f, 0.0f }, { 1.0f, 0.0f }, { 1.0f, 1.0f }, { 0.0f, 1.0f } }; + for (const ImVec2& p : pos_norms) + draw_list->PathLineTo(ImVec2(x + 0.5f + (int)(sz * p.x), y + 0.5f + (int)(sz * p.y))); +} + // Demonstrate using the low-level ImDrawList to draw custom shapes. static void ShowExampleAppCustomRendering(bool* p_open) { @@ -8047,12 +8209,14 @@ static void ShowExampleAppCustomRendering(bool* p_open) float th = (n == 0) ? 1.0f : thickness; draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle - draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, sz*0.3f, col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse + draw_list->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), ImVec2(sz*0.5f, sz*0.3f), col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle //draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle + PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, ImDrawFlags_Closed, th); x += sz + spacing; // Concave Shape + //draw_list->AddPolyline(concave_shape, IM_ARRAYSIZE(concave_shape), col, ImDrawFlags_Closed, th); draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line @@ -8076,12 +8240,13 @@ static void ShowExampleAppCustomRendering(bool* p_open) // Filled shapes draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, ngon_sides); x += sz + spacing; // N-gon draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, circle_segments); x += sz + spacing; // Circle - draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, sz * 0.3f, col, -0.3f, circle_segments); x += sz + spacing;// Ellipse + draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), ImVec2(sz * 0.5f, sz * 0.3f), col, -0.3f, circle_segments); x += sz + spacing;// Ellipse draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col); x += sz + spacing; // Triangle //draw_list->AddTriangleFilled(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col); x += sz*0.4f + spacing; // Thin triangle + PathConcaveShape(draw_list, x, y, sz); draw_list->PathFillConcave(col); x += sz + spacing; // Concave shape draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + thickness), col); x += sz + spacing; // Horizontal line (faster than AddLine, but only handle integer thickness) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + thickness, y + sz), col); x += spacing * 2.0f;// Vertical line (faster than AddLine, but only handle integer thickness) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine) @@ -8097,15 +8262,10 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->PathFillConvex(col); x += sz + spacing; - // Cubic Bezier Curve (4 control points): this is concave so not drawing it yet - //draw_list->PathLineTo(ImVec2(x + cp4[0].x, y + cp4[0].y)); - //draw_list->PathBezierCubicCurveTo(ImVec2(x + cp4[1].x, y + cp4[1].y), ImVec2(x + cp4[2].x, y + cp4[2].y), ImVec2(x + cp4[3].x, y + cp4[3].y), curve_segments); - //draw_list->PathFillConvex(col); - //x += sz + spacing; - draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); + x += sz + spacing; - ImGui::Dummy(ImVec2((sz + spacing) * 12.2f, (sz + spacing) * 3.0f)); + ImGui::Dummy(ImVec2((sz + spacing) * 13.2f, (sz + spacing) * 3.0f)); ImGui::PopItemWidth(); ImGui::EndTabItem(); } @@ -8275,92 +8435,119 @@ static void ShowExampleAppCustomRendering(bool* p_open) // Simplified structure to mimic a Document model struct MyDocument { - const char* Name; // Document title + char Name[32]; // Document title + int UID; // Unique ID (necessary as we can change title) bool Open; // Set when open (we keep an array of all available documents to simplify demo code!) bool OpenPrev; // Copy of Open from last update. bool Dirty; // Set when the document has been modified - bool WantClose; // Set when the document ImVec4 Color; // An arbitrary variable associated to the document - MyDocument(const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f)) + MyDocument(int uid, const char* name, bool open = true, const ImVec4& color = ImVec4(1.0f, 1.0f, 1.0f, 1.0f)) { - Name = name; + UID = uid; + snprintf(Name, sizeof(Name), "%s", name); Open = OpenPrev = open; Dirty = false; - WantClose = false; Color = color; } void DoOpen() { Open = true; } - void DoQueueClose() { WantClose = true; } void DoForceClose() { Open = false; Dirty = false; } void DoSave() { Dirty = false; } +}; + +struct ExampleAppDocuments +{ + ImVector Documents; + ImVector CloseQueue; + MyDocument* RenamingDoc = NULL; + bool RenamingStarted = false; + + ExampleAppDocuments() + { + Documents.push_back(MyDocument(0, "Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f))); + Documents.push_back(MyDocument(1, "Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f))); + Documents.push_back(MyDocument(2, "Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f))); + Documents.push_back(MyDocument(3, "Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f))); + Documents.push_back(MyDocument(4, "A Rather Long Title", false, ImVec4(0.4f, 0.8f, 0.8f, 1.0f))); + Documents.push_back(MyDocument(5, "Some Document", false, ImVec4(0.8f, 0.8f, 1.0f, 1.0f))); + } + + // As we allow to change document name, we append a never-changing document ID so tabs are stable + void GetTabName(MyDocument* doc, char* out_buf, size_t out_buf_size) + { + snprintf(out_buf, out_buf_size, "%s###doc%d", doc->Name, doc->UID); + } // Display placeholder contents for the Document - static void DisplayContents(MyDocument* doc) + void DisplayDocContents(MyDocument* doc) { ImGui::PushID(doc); ImGui::Text("Document \"%s\"", doc->Name); ImGui::PushStyleColor(ImGuiCol_Text, doc->Color); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); ImGui::PopStyleColor(); - if (ImGui::Button("Modify", ImVec2(100, 0))) + + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_R, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Rename..")) + { + RenamingDoc = doc; + RenamingStarted = true; + } + ImGui::SameLine(); + + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_M, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Modify")) doc->Dirty = true; + ImGui::SameLine(); - if (ImGui::Button("Save", ImVec2(100, 0))) + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_S, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Save")) doc->DoSave(); + + ImGui::SameLine(); + ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_W, ImGuiInputFlags_Tooltip); + if (ImGui::Button("Close")) + CloseQueue.push_back(doc); ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior. ImGui::PopID(); } // Display context menu for the Document - static void DisplayContextMenu(MyDocument* doc) + void DisplayDocContextMenu(MyDocument* doc) { if (!ImGui::BeginPopupContextItem()) return; char buf[256]; sprintf(buf, "Save %s", doc->Name); - if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open)) + if (ImGui::MenuItem(buf, "Ctrl+S", false, doc->Open)) doc->DoSave(); - if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open)) - doc->DoQueueClose(); + if (ImGui::MenuItem("Rename...", "Ctrl+R", false, doc->Open)) + RenamingDoc = doc; + if (ImGui::MenuItem("Close", "Ctrl+W", false, doc->Open)) + CloseQueue.push_back(doc); ImGui::EndPopup(); } -}; - -struct ExampleAppDocuments -{ - ImVector Documents; - ExampleAppDocuments() + // [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface. + // If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo, + // as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for + // the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has + // disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively + // give the impression of a flicker for one frame. + // We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch. + // Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag. + void NotifyOfDocumentsClosedElsewhere() { - Documents.push_back(MyDocument("Lettuce", true, ImVec4(0.4f, 0.8f, 0.4f, 1.0f))); - Documents.push_back(MyDocument("Eggplant", true, ImVec4(0.8f, 0.5f, 1.0f, 1.0f))); - Documents.push_back(MyDocument("Carrot", true, ImVec4(1.0f, 0.8f, 0.5f, 1.0f))); - Documents.push_back(MyDocument("Tomato", false, ImVec4(1.0f, 0.3f, 0.4f, 1.0f))); - Documents.push_back(MyDocument("A Rather Long Title", false)); - Documents.push_back(MyDocument("Some Document", false)); + for (MyDocument& doc : Documents) + { + if (!doc.Open && doc.OpenPrev) + ImGui::SetTabItemClosed(doc.Name); + doc.OpenPrev = doc.Open; + } } }; -// [Optional] Notify the system of Tabs/Windows closure that happened outside the regular tab interface. -// If a tab has been closed programmatically (aka closed from another source such as the Checkbox() in the demo, -// as opposed to clicking on the regular tab closing button) and stops being submitted, it will take a frame for -// the tab bar to notice its absence. During this frame there will be a gap in the tab bar, and if the tab that has -// disappeared was the selected one, the tab bar will report no selected tab during the frame. This will effectively -// give the impression of a flicker for one frame. -// We call SetTabItemClosed() to manually notify the Tab Bar or Docking system of removed tabs to avoid this glitch. -// Note that this completely optional, and only affect tab bars with the ImGuiTabBarFlags_Reorderable flag. -static void NotifyOfDocumentsClosedElsewhere(ExampleAppDocuments& app) -{ - for (MyDocument& doc : app.Documents) - { - if (!doc.Open && doc.OpenPrev) - ImGui::SetTabItemClosed(doc.Name); - doc.OpenPrev = doc.Open; - } -} - void ShowExampleAppDocuments(bool* p_open) { static ExampleAppDocuments app; @@ -8394,8 +8581,8 @@ void ShowExampleAppDocuments(bool* p_open) } if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0)) for (MyDocument& doc : app.Documents) - doc.DoQueueClose(); - if (ImGui::MenuItem("Exit", "Ctrl+F4") && p_open) + app.CloseQueue.push_back(&doc); + if (ImGui::MenuItem("Exit") && p_open) *p_open = false; ImGui::EndMenu(); } @@ -8433,7 +8620,7 @@ void ShowExampleAppDocuments(bool* p_open) if (ImGui::BeginTabBar("##tabs", tab_bar_flags)) { if (opt_reorderable) - NotifyOfDocumentsClosedElsewhere(app); + app.NotifyOfDocumentsClosedElsewhere(); // [DEBUG] Stress tests //if ((ImGui::GetFrameCount() % 30) == 0) docs[1].Open ^= 1; // [DEBUG] Automatically show/hide a tab. Test various interactions e.g. dragging with this on. @@ -8445,20 +8632,23 @@ void ShowExampleAppDocuments(bool* p_open) if (!doc.Open) continue; + // As we allow to change document name, we append a never-changing document id so tabs are stable + char doc_name_buf[64]; + app.GetTabName(&doc, doc_name_buf, sizeof(doc_name_buf)); ImGuiTabItemFlags tab_flags = (doc.Dirty ? ImGuiTabItemFlags_UnsavedDocument : 0); - bool visible = ImGui::BeginTabItem(doc.Name, &doc.Open, tab_flags); + bool visible = ImGui::BeginTabItem(doc_name_buf, &doc.Open, tab_flags); // Cancel attempt to close when unsaved add to save queue so we can display a popup. if (!doc.Open && doc.Dirty) { doc.Open = true; - doc.DoQueueClose(); + app.CloseQueue.push_back(&doc); } - MyDocument::DisplayContextMenu(&doc); + app.DisplayDocContextMenu(&doc); if (visible) { - MyDocument::DisplayContents(&doc); + app.DisplayDocContents(&doc); ImGui::EndTabItem(); } } @@ -8467,33 +8657,44 @@ void ShowExampleAppDocuments(bool* p_open) } } - // Update closing queue - static ImVector close_queue; - if (close_queue.empty()) + // Display renaming UI + if (app.RenamingDoc != NULL) { - // Close queue is locked once we started a popup - for (MyDocument& doc : app.Documents) - if (doc.WantClose) + if (app.RenamingStarted) + ImGui::OpenPopup("Rename"); + if (ImGui::BeginPopup("Rename")) + { + ImGui::SetNextItemWidth(ImGui::GetFontSize() * 30); + if (ImGui::InputText("###Name", app.RenamingDoc->Name, IM_ARRAYSIZE(app.RenamingDoc->Name), ImGuiInputTextFlags_EnterReturnsTrue)) { - doc.WantClose = false; - close_queue.push_back(&doc); + ImGui::CloseCurrentPopup(); + app.RenamingDoc = NULL; } + if (app.RenamingStarted) + ImGui::SetKeyboardFocusHere(-1); + ImGui::EndPopup(); + } + else + { + app.RenamingDoc = NULL; + } + app.RenamingStarted = false; } // Display closing confirmation UI - if (!close_queue.empty()) + if (!app.CloseQueue.empty()) { int close_queue_unsaved_documents = 0; - for (int n = 0; n < close_queue.Size; n++) - if (close_queue[n]->Dirty) + for (int n = 0; n < app.CloseQueue.Size; n++) + if (app.CloseQueue[n]->Dirty) close_queue_unsaved_documents++; if (close_queue_unsaved_documents == 0) { // Close documents when all are unsaved - for (int n = 0; n < close_queue.Size; n++) - close_queue[n]->DoForceClose(); - close_queue.clear(); + for (int n = 0; n < app.CloseQueue.Size; n++) + app.CloseQueue[n]->DoForceClose(); + app.CloseQueue.clear(); } else { @@ -8504,37 +8705,35 @@ void ShowExampleAppDocuments(bool* p_open) ImGui::Text("Save change to the following items?"); float item_height = ImGui::GetTextLineHeightWithSpacing(); if (ImGui::BeginChild(ImGui::GetID("frame"), ImVec2(-FLT_MIN, 6.25f * item_height), ImGuiChildFlags_FrameStyle)) - { - for (int n = 0; n < close_queue.Size; n++) - if (close_queue[n]->Dirty) - ImGui::Text("%s", close_queue[n]->Name); - } + for (MyDocument* doc : app.CloseQueue) + if (doc->Dirty) + ImGui::Text("%s", doc->Name); ImGui::EndChild(); ImVec2 button_size(ImGui::GetFontSize() * 7.0f, 0.0f); if (ImGui::Button("Yes", button_size)) { - for (int n = 0; n < close_queue.Size; n++) + for (MyDocument* doc : app.CloseQueue) { - if (close_queue[n]->Dirty) - close_queue[n]->DoSave(); - close_queue[n]->DoForceClose(); + if (doc->Dirty) + doc->DoSave(); + doc->DoForceClose(); } - close_queue.clear(); + app.CloseQueue.clear(); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("No", button_size)) { - for (int n = 0; n < close_queue.Size; n++) - close_queue[n]->DoForceClose(); - close_queue.clear(); + for (MyDocument* doc : app.CloseQueue) + doc->DoForceClose(); + app.CloseQueue.clear(); ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if (ImGui::Button("Cancel", button_size)) { - close_queue.clear(); + app.CloseQueue.clear(); ImGui::CloseCurrentPopup(); } ImGui::EndPopup(); diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_draw.cpp b/libs/bgfx/3rdparty/dear-imgui/imgui_draw.cpp index 1319a6e..171889f 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_draw.cpp +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (drawing and font code) /* @@ -8,6 +8,7 @@ Index of this file: // [SECTION] STB libraries implementation // [SECTION] Style functions // [SECTION] ImDrawList +// [SECTION] ImTriangulator, ImDrawList concave polygon fill // [SECTION] ImDrawListSplitter // [SECTION] ImDrawData // [SECTION] Helpers ShadeVertsXXX functions @@ -64,6 +65,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double. #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision #pragma clang diagnostic ignored "-Wreserved-identifier" // warning: identifier '_Xxx' is reserved because it starts with '_' followed by a capital letter +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used @@ -383,6 +385,7 @@ void ImDrawListSharedData::SetCircleTessellationMaxError(float max_error) } // Initialize before use in a new frame. We always have a command ready in the buffer. +// In the majority of cases, you would want to call PushClipRect() and PushTextureID() after this. void ImDrawList::_ResetForNewFrame() { // Verify that the ImDrawCmd fields we want to memcmp() are contiguous in memory. @@ -1217,10 +1220,10 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa } } -void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments) +void ImDrawList::PathEllipticalArcTo(const ImVec2& center, const ImVec2& radius, float rot, float a_min, float a_max, int num_segments) { if (num_segments <= 0) - num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here. _Path.reserve(_Path.Size + (num_segments + 1)); @@ -1229,11 +1232,10 @@ void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float for (int i = 0; i <= num_segments; i++) { const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); - ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y); - const float rel_x = (point.x * cos_rot) - (point.y * sin_rot); - const float rel_y = (point.x * sin_rot) + (point.y * cos_rot); - point.x = rel_x + center.x; - point.y = rel_y + center.y; + ImVec2 point(ImCos(a) * radius.x, ImSin(a) * radius.y); + const ImVec2 rel((point.x * cos_rot) - (point.y * sin_rot), (point.x * sin_rot) + (point.y * cos_rot)); + point.x = rel.x + center.x; + point.y = rel.y + center.y; _Path.push_back(point); } } @@ -1558,31 +1560,31 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in } // Ellipse -void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness) +void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments, float thickness) { if ((col & IM_COL32_A_MASK) == 0) return; if (num_segments <= 0) - num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here. // 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; - PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1); + PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1); PathStroke(col, true, thickness); } -void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments) +void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments) { if ((col & IM_COL32_A_MASK) == 0) return; if (num_segments <= 0) - num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius.x, radius.y)); // A bit pessimistic, maybe there's a better computation to do here. // 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; - PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1); + PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1); PathFillConvex(col); } @@ -1613,10 +1615,11 @@ void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, if ((col & IM_COL32_A_MASK) == 0) return; + // Accept null ranges + if (text_begin == text_end || text_begin[0] == 0) + return; if (text_end == NULL) text_end = text_begin + strlen(text_begin); - if (text_begin == text_end) - return; // Pull default font/size from the shared ImDrawListSharedData instance if (font == NULL) @@ -1700,6 +1703,316 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi PopTextureID(); } +//----------------------------------------------------------------------------- +// [SECTION] ImTriangulator, ImDrawList concave polygon fill +//----------------------------------------------------------------------------- +// Triangulate concave polygons. Based on "Triangulation by Ear Clipping" paper, O(N^2) complexity. +// Reference: https://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf +// Provided as a convenience for user but not used by main library. +//----------------------------------------------------------------------------- +// - ImTriangulator [Internal] +// - AddConcavePolyFilled() +//----------------------------------------------------------------------------- + +enum ImTriangulatorNodeType +{ + ImTriangulatorNodeType_Convex, + ImTriangulatorNodeType_Ear, + ImTriangulatorNodeType_Reflex +}; + +struct ImTriangulatorNode +{ + ImTriangulatorNodeType Type; + int Index; + ImVec2 Pos; + ImTriangulatorNode* Next; + ImTriangulatorNode* Prev; + + void Unlink() { Next->Prev = Prev; Prev->Next = Next; } +}; + +struct ImTriangulatorNodeSpan +{ + ImTriangulatorNode** Data = NULL; + int Size = 0; + + void push_back(ImTriangulatorNode* node) { Data[Size++] = node; } + void find_erase_unsorted(int idx) { for (int i = Size - 1; i >= 0; i--) if (Data[i]->Index == idx) { Data[i] = Data[Size - 1]; Size--; return; } } +}; + +struct ImTriangulator +{ + static int EstimateTriangleCount(int points_count) { return (points_count < 3) ? 0 : points_count - 2; } + static int EstimateScratchBufferSize(int points_count) { return sizeof(ImTriangulatorNode) * points_count + sizeof(ImTriangulatorNode*) * points_count * 2; } + + void Init(const ImVec2* points, int points_count, void* scratch_buffer); + void GetNextTriangle(unsigned int out_triangle[3]); // Return relative indexes for next triangle + + // Internal functions + void BuildNodes(const ImVec2* points, int points_count); + void BuildReflexes(); + void BuildEars(); + void FlipNodeList(); + bool IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const; + void ReclassifyNode(ImTriangulatorNode* node); + + // Internal members + int _TrianglesLeft = 0; + ImTriangulatorNode* _Nodes = NULL; + ImTriangulatorNodeSpan _Ears; + ImTriangulatorNodeSpan _Reflexes; +}; + +// Distribute storage for nodes, ears and reflexes. +// FIXME-OPT: if everything is convex, we could report it to caller and let it switch to an convex renderer +// (this would require first building reflexes to bail to convex if empty, without even building nodes) +void ImTriangulator::Init(const ImVec2* points, int points_count, void* scratch_buffer) +{ + IM_ASSERT(scratch_buffer != NULL && points_count >= 3); + _TrianglesLeft = EstimateTriangleCount(points_count); + _Nodes = (ImTriangulatorNode*)scratch_buffer; // points_count x Node + _Ears.Data = (ImTriangulatorNode**)(_Nodes + points_count); // points_count x Node* + _Reflexes.Data = (ImTriangulatorNode**)(_Nodes + points_count) + points_count; // points_count x Node* + BuildNodes(points, points_count); + BuildReflexes(); + BuildEars(); +} + +void ImTriangulator::BuildNodes(const ImVec2* points, int points_count) +{ + for (int i = 0; i < points_count; i++) + { + _Nodes[i].Type = ImTriangulatorNodeType_Convex; + _Nodes[i].Index = i; + _Nodes[i].Pos = points[i]; + _Nodes[i].Next = _Nodes + i + 1; + _Nodes[i].Prev = _Nodes + i - 1; + } + _Nodes[0].Prev = _Nodes + points_count - 1; + _Nodes[points_count - 1].Next = _Nodes; +} + +void ImTriangulator::BuildReflexes() +{ + ImTriangulatorNode* n1 = _Nodes; + for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next) + { + if (ImTriangleIsClockwise(n1->Prev->Pos, n1->Pos, n1->Next->Pos)) + continue; + n1->Type = ImTriangulatorNodeType_Reflex; + _Reflexes.push_back(n1); + } +} + +void ImTriangulator::BuildEars() +{ + ImTriangulatorNode* n1 = _Nodes; + for (int i = _TrianglesLeft; i >= 0; i--, n1 = n1->Next) + { + if (n1->Type != ImTriangulatorNodeType_Convex) + continue; + if (!IsEar(n1->Prev->Index, n1->Index, n1->Next->Index, n1->Prev->Pos, n1->Pos, n1->Next->Pos)) + continue; + n1->Type = ImTriangulatorNodeType_Ear; + _Ears.push_back(n1); + } +} + +void ImTriangulator::GetNextTriangle(unsigned int out_triangle[3]) +{ + if (_Ears.Size == 0) + { + FlipNodeList(); + + ImTriangulatorNode* node = _Nodes; + for (int i = _TrianglesLeft; i >= 0; i--, node = node->Next) + node->Type = ImTriangulatorNodeType_Convex; + _Reflexes.Size = 0; + BuildReflexes(); + BuildEars(); + + // If we still don't have ears, it means geometry is degenerated. + if (_Ears.Size == 0) + { + // Return first triangle available, mimicking the behavior of convex fill. + IM_ASSERT(_TrianglesLeft > 0); // Geometry is degenerated + _Ears.Data[0] = _Nodes; + _Ears.Size = 1; + } + } + + ImTriangulatorNode* ear = _Ears.Data[--_Ears.Size]; + out_triangle[0] = ear->Prev->Index; + out_triangle[1] = ear->Index; + out_triangle[2] = ear->Next->Index; + + ear->Unlink(); + if (ear == _Nodes) + _Nodes = ear->Next; + + ReclassifyNode(ear->Prev); + ReclassifyNode(ear->Next); + _TrianglesLeft--; +} + +void ImTriangulator::FlipNodeList() +{ + ImTriangulatorNode* prev = _Nodes; + ImTriangulatorNode* temp = _Nodes; + ImTriangulatorNode* current = _Nodes->Next; + prev->Next = prev; + prev->Prev = prev; + while (current != _Nodes) + { + temp = current->Next; + + current->Next = prev; + prev->Prev = current; + _Nodes->Next = current; + current->Prev = _Nodes; + + prev = current; + current = temp; + } + _Nodes = prev; +} + +// A triangle is an ear is no other vertex is inside it. We can test reflexes vertices only (see reference algorithm) +bool ImTriangulator::IsEar(int i0, int i1, int i2, const ImVec2& v0, const ImVec2& v1, const ImVec2& v2) const +{ + ImTriangulatorNode** p_end = _Reflexes.Data + _Reflexes.Size; + for (ImTriangulatorNode** p = _Reflexes.Data; p < p_end; p++) + { + ImTriangulatorNode* reflex = *p; + if (reflex->Index != i0 && reflex->Index != i1 && reflex->Index != i2) + if (ImTriangleContainsPoint(v0, v1, v2, reflex->Pos)) + return false; + } + return true; +} + +void ImTriangulator::ReclassifyNode(ImTriangulatorNode* n1) +{ + // Classify node + ImTriangulatorNodeType type; + const ImTriangulatorNode* n0 = n1->Prev; + const ImTriangulatorNode* n2 = n1->Next; + if (!ImTriangleIsClockwise(n0->Pos, n1->Pos, n2->Pos)) + type = ImTriangulatorNodeType_Reflex; + else if (IsEar(n0->Index, n1->Index, n2->Index, n0->Pos, n1->Pos, n2->Pos)) + type = ImTriangulatorNodeType_Ear; + else + type = ImTriangulatorNodeType_Convex; + + // Update lists when a type changes + if (type == n1->Type) + return; + if (n1->Type == ImTriangulatorNodeType_Reflex) + _Reflexes.find_erase_unsorted(n1->Index); + else if (n1->Type == ImTriangulatorNodeType_Ear) + _Ears.find_erase_unsorted(n1->Index); + if (type == ImTriangulatorNodeType_Reflex) + _Reflexes.push_back(n1); + else if (type == ImTriangulatorNodeType_Ear) + _Ears.push_back(n1); + n1->Type = type; +} + +// Use ear-clipping algorithm to triangulate a simple polygon (no self-interaction, no holes). +// (Reminder: we don't perform any coarse clipping/culling in ImDrawList layer! +// It is up to caller to ensure not making costly calls that will be outside of visible area. +// As concave fill is noticeably more expensive than other primitives, be mindful of this... +// Caller can build AABB of points, and avoid filling if 'draw_list->_CmdHeader.ClipRect.Overlays(points_bb) == false') +void ImDrawList::AddConcavePolyFilled(const ImVec2* points, const int points_count, ImU32 col) +{ + if (points_count < 3 || (col & IM_COL32_A_MASK) == 0) + return; + + const ImVec2 uv = _Data->TexUvWhitePixel; + ImTriangulator triangulator; + unsigned int triangle[3]; + if (Flags & ImDrawListFlags_AntiAliasedFill) + { + // Anti-aliased Fill + const float AA_SIZE = _FringeScale; + const ImU32 col_trans = col & ~IM_COL32_A_MASK; + const int idx_count = (points_count - 2) * 3 + points_count * 6; + const int vtx_count = (points_count * 2); + PrimReserve(idx_count, vtx_count); + + // Add indexes for fill + unsigned int vtx_inner_idx = _VtxCurrentIdx; + unsigned int vtx_outer_idx = _VtxCurrentIdx + 1; + + _Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2)); + triangulator.Init(points, points_count, _Data->TempBuffer.Data); + while (triangulator._TrianglesLeft > 0) + { + triangulator.GetNextTriangle(triangle); + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (triangle[0] << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (triangle[1] << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (triangle[2] << 1)); + _IdxWritePtr += 3; + } + + // Compute normals + _Data->TempBuffer.reserve_discard(points_count); + ImVec2* temp_normals = _Data->TempBuffer.Data; + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + const ImVec2& p0 = points[i0]; + const ImVec2& p1 = points[i1]; + float dx = p1.x - p0.x; + float dy = p1.y - p0.y; + IM_NORMALIZE2F_OVER_ZERO(dx, dy); + temp_normals[i0].x = dy; + temp_normals[i0].y = -dx; + } + + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + // Average normals + const ImVec2& n0 = temp_normals[i0]; + const ImVec2& n1 = temp_normals[i1]; + float dm_x = (n0.x + n1.x) * 0.5f; + float dm_y = (n0.y + n1.y) * 0.5f; + IM_FIXNORMAL2F(dm_x, dm_y); + dm_x *= AA_SIZE * 0.5f; + dm_y *= AA_SIZE * 0.5f; + + // Add vertices + _VtxWritePtr[0].pos.x = (points[i1].x - dm_x); _VtxWritePtr[0].pos.y = (points[i1].y - dm_y); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos.x = (points[i1].x + dm_x); _VtxWritePtr[1].pos.y = (points[i1].y + dm_y); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer + _VtxWritePtr += 2; + + // Add indexes for fringes + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); + _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); + _IdxWritePtr += 6; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Fill + const int idx_count = (points_count - 2) * 3; + const int vtx_count = points_count; + PrimReserve(idx_count, vtx_count); + for (int i = 0; i < vtx_count; i++) + { + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; + _VtxWritePtr++; + } + _Data->TempBuffer.reserve_discard((ImTriangulator::EstimateScratchBufferSize(points_count) + sizeof(ImVec2)) / sizeof(ImVec2)); + triangulator.Init(points, points_count, _Data->TempBuffer.Data); + while (triangulator._TrianglesLeft > 0) + { + triangulator.GetNextTriangle(triangle); + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx + triangle[0]); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + triangle[1]); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + triangle[2]); + _IdxWritePtr += 3; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } +} //----------------------------------------------------------------------------- // [SECTION] ImDrawListSplitter @@ -2672,8 +2985,8 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) int unscaled_ascent, unscaled_descent, unscaled_line_gap; stbtt_GetFontVMetrics(&src_tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); - const float ascent = ImTrunc(unscaled_ascent * font_scale + ((unscaled_ascent > 0.0f) ? +1 : -1)); - const float descent = ImTrunc(unscaled_descent * font_scale + ((unscaled_descent > 0.0f) ? +1 : -1)); + const float ascent = ImCeil(unscaled_ascent * font_scale); + const float descent = ImFloor(unscaled_descent * font_scale); ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); const float font_off_x = cfg.GlyphOffset.x; const float font_off_y = cfg.GlyphOffset.y + IM_ROUND(dst_font->Ascent); @@ -3768,6 +4081,8 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, Im { x = start_x; y += line_height; + if (y > clip_rect.w) + break; // break out of main loop word_wrap_eol = NULL; s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks continue; diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_internal.h b/libs/bgfx/3rdparty/dear-imgui/imgui_internal.h index 4ac8b1c..244cda1 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_internal.h +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. @@ -14,8 +14,8 @@ Index of this file: // [SECTION] Macros // [SECTION] Generic helpers // [SECTION] ImDrawList support -// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Data types support +// [SECTION] Widgets support: flags, enums, data structures // [SECTION] Popup support // [SECTION] Inputs support // [SECTION] Clipper support @@ -87,6 +87,8 @@ Index of this file: #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' +#pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind @@ -124,7 +126,7 @@ struct ImDrawListSharedData; // Data shared between all ImDrawList instan struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiContext; // Main Dear ImGui context struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine -struct ImGuiDataVarInfo; // Variable information (e.g. to avoid style variables from an enum) +struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum) struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box @@ -146,6 +148,7 @@ struct ImGuiStyleMod; // Stacked style modifier, backup of modifie struct ImGuiTabBar; // Storage for a tab bar struct ImGuiTabItem; // Storage for a tab item (within a tab bar) struct ImGuiTable; // Storage for a table +struct ImGuiTableHeaderData; // Storage for TableAngledHeadersRow() struct ImGuiTableColumn; // Storage for one column of a table struct ImGuiTableInstanceData; // Storage for one instance of a same table struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables. @@ -166,7 +169,6 @@ typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // E typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow(); -typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc. typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() @@ -179,6 +181,7 @@ typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // F typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx() typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx() typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest() +typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy() typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...); @@ -345,6 +348,7 @@ namespace ImStb // - Helper: ImPool<> // - Helper: ImChunkStream<> // - Helper: ImGuiTextIndex +// - Helper: ImGuiStorage //----------------------------------------------------------------------------- // Helpers: Hashing @@ -404,6 +408,7 @@ IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end); // return number of bytes to express one char in UTF-8 IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8 IMGUI_API const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_text_curr); // return previous UTF-8 code-point. +IMGUI_API int ImTextCountLines(const char* in_text, const char* in_text_end); // return number of lines taken by text. trailing carriage return doesn't count as an extra line. // Helpers: File System #ifdef IMGUI_DISABLE_FILE_FUNCTIONS @@ -468,7 +473,7 @@ template static inline T ImSubClampOverflow(T a, T b, T mn, T mx) // - Misc maths helpers static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } -static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); } +static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } @@ -498,7 +503,8 @@ IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); -inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } +inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } +inline bool ImTriangleIsClockwise(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0f; } // Helper: ImVec1 (1D vector) // (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches) @@ -717,7 +723,7 @@ struct ImChunkStream void swap(ImChunkStream& rhs) { rhs.Buf.swap(Buf); } }; -// Helper: ImGuiTextIndex<> +// Helper: ImGuiTextIndex // Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API. struct ImGuiTextIndex { @@ -731,6 +737,8 @@ struct ImGuiTextIndex void append(const char* base, int old_size, int new_size); }; +// Helper: ImGuiStorage +IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key); //----------------------------------------------------------------------------- // [SECTION] ImDrawList support //----------------------------------------------------------------------------- @@ -793,6 +801,40 @@ struct ImDrawDataBuilder ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); } }; +//----------------------------------------------------------------------------- +// [SECTION] Data types support +//----------------------------------------------------------------------------- + +struct ImGuiDataVarInfo +{ + ImGuiDataType Type; + ImU32 Count; // 1+ + ImU32 Offset; // Offset in parent structure + void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } +}; + +struct ImGuiDataTypeStorage +{ + ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT +}; + +// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). +struct ImGuiDataTypeInfo +{ + size_t Size; // Size in bytes + const char* Name; // Short descriptive name for the type, for debugging + const char* PrintFmt; // Default printf format for the type + const char* ScanFmt; // Default scanf format for the type +}; + +// Extend ImGuiDataType_ +enum ImGuiDataTypePrivate_ +{ + ImGuiDataType_String = ImGuiDataType_COUNT + 1, + ImGuiDataType_Pointer, + ImGuiDataType_ID, +}; + //----------------------------------------------------------------------------- // [SECTION] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- @@ -836,7 +878,8 @@ enum ImGuiItemStatusFlags_ ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. ImGuiItemStatusFlags_Visible = 1 << 8, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()). - ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid + ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid. + ImGuiItemStatusFlags_HasShortcut = 1 << 10, // g.LastItemData.Shortcut valid. Set by SetNextItemShortcut() -> ItemAdd(). // Additional status + semantic for ImGuiTestEngine #ifdef IMGUI_ENABLE_TEST_ENGINE @@ -863,6 +906,7 @@ enum ImGuiInputTextFlagsPrivate_ ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline() ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. + ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 29, // For internal use by InputScalar() and TempInputScalar() }; // Extend ImGuiButtonFlags_ @@ -882,7 +926,7 @@ enum ImGuiButtonFlagsPrivate_ 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) - ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) + ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used every time an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) @@ -1111,6 +1155,15 @@ struct IMGUI_API ImGuiInputTextState }; +enum ImGuiWindowRefreshFlags_ +{ + ImGuiWindowRefreshFlags_None = 0, + ImGuiWindowRefreshFlags_TryToAvoidRefresh = 1 << 0, // [EXPERIMENTAL] Try to keep existing contents, USER MUST NOT HONOR BEGIN() RETURNING FALSE AND NOT APPEND. + ImGuiWindowRefreshFlags_RefreshOnHover = 1 << 1, // [EXPERIMENTAL] Always refresh on hover + ImGuiWindowRefreshFlags_RefreshOnFocus = 1 << 2, // [EXPERIMENTAL] Always refresh on focus + // Refresh policy/frequency, Load Balancing etc. +}; + enum ImGuiNextWindowDataFlags_ { ImGuiNextWindowDataFlags_None = 0, @@ -1123,6 +1176,7 @@ enum ImGuiNextWindowDataFlags_ ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, ImGuiNextWindowDataFlags_HasScroll = 1 << 7, ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8, + ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 9, }; // Storage for SetNexWindow** functions @@ -1144,6 +1198,7 @@ struct ImGuiNextWindowData void* SizeCallbackUserData; float BgAlphaVal; // Override background alpha ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?) + ImGuiWindowRefreshFlags RefreshFlagsVal; ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); } inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } @@ -1159,6 +1214,7 @@ enum ImGuiNextItemDataFlags_ ImGuiNextItemDataFlags_HasWidth = 1 << 0, ImGuiNextItemDataFlags_HasOpen = 1 << 1, ImGuiNextItemDataFlags_HasShortcut = 1 << 2, + ImGuiNextItemDataFlags_HasRefVal = 1 << 3, }; struct ImGuiNextItemData @@ -1169,8 +1225,10 @@ struct ImGuiNextItemData ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values) float Width; // Set by SetNextItemWidth() ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut() + ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut() bool OpenVal; // Set by SetNextItemOpen() - ImGuiCond OpenCond : 8; + ImU8 OpenCond; // Set by SetNextItemOpen() + ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! @@ -1184,9 +1242,10 @@ struct ImGuiLastItemData ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ ImRect Rect; // Full rectangle ImRect NavRect; // Navigation scoring rectangle (not displayed) - // Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags is set. - ImRect DisplayRect; // Display rectangle (ONLY VALID IF ImGuiItemStatusFlags_HasDisplayRect is set) - ImRect ClipRect; // Clip rectangle at the time of submitting item (ONLY VALID IF ImGuiItemStatusFlags_HasClipRect is set) + // Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set. + ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set. + ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set.. + ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set.. ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } }; @@ -1223,7 +1282,8 @@ struct ImGuiWindowStackData { ImGuiWindow* Window; ImGuiLastItemData ParentLastItemDataBackup; - ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting + ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting + bool DisabledOverrideReenable; // Non-child window override disabled flag }; struct ImGuiShrinkWidthItem @@ -1242,40 +1302,6 @@ struct ImGuiPtrOrIndex ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } }; -//----------------------------------------------------------------------------- -// [SECTION] Data types support -//----------------------------------------------------------------------------- - -struct ImGuiDataVarInfo -{ - ImGuiDataType Type; - ImU32 Count; // 1+ - ImU32 Offset; // Offset in parent structure - void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } -}; - -struct ImGuiDataTypeTempStorage -{ - ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT -}; - -// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). -struct ImGuiDataTypeInfo -{ - size_t Size; // Size in bytes - const char* Name; // Short descriptive name for the type, for debugging - const char* PrintFmt; // Default printf format for the type - const char* ScanFmt; // Default scanf format for the type -}; - -// Extend ImGuiDataType_ -enum ImGuiDataTypePrivate_ -{ - ImGuiDataType_String = ImGuiDataType_COUNT + 1, - ImGuiDataType_Pointer, - ImGuiDataType_ID, -}; - //----------------------------------------------------------------------------- // [SECTION] Popup support //----------------------------------------------------------------------------- @@ -1292,7 +1318,7 @@ struct ImGuiPopupData { ImGuiID PopupId; // Set on OpenPopup() ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() - ImGuiWindow* BackupNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close + ImGuiWindow* RestoreNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value int OpenFrameCount; // Set on OpenPopup() ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) @@ -1349,7 +1375,6 @@ enum ImGuiInputSource ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them. ImGuiInputSource_Keyboard, ImGuiInputSource_Gamepad, - ImGuiInputSource_Clipboard, // Currently only used by InputText() ImGuiInputSource_COUNT }; @@ -1383,7 +1408,8 @@ struct ImGuiInputEvent // Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior. #define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. -#define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner. +#define ImGuiKeyOwner_NoOwner ((ImGuiID)-1) // Require key to have no owner. +//#define ImGuiKeyOwner_None ImGuiKeyOwner_NoOwner // We previously called this 'ImGuiKeyOwner_None' but it was inconsistent with our pattern that _None values == 0 and quite dangerous. Also using _NoOwner makes the IsKeyPressed() calls more explicit. typedef ImS16 ImGuiKeyRoutingIndex; @@ -1391,13 +1417,13 @@ typedef ImS16 ImGuiKeyRoutingIndex; struct ImGuiKeyRoutingData { ImGuiKeyRoutingIndex NextEntryIndex; - ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImGuiMod_Shortcut is already translated to Ctrl/Super. + ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImU8 RoutingCurrScore; // [DEBUG] For debug display ImU8 RoutingNextScore; // Lower is better (0: perfect score) ImGuiID RoutingCurr; ImGuiID RoutingNext; - ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; } + ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; } }; // Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching. @@ -1421,73 +1447,47 @@ struct ImGuiKeyOwnerData bool LockThisFrame; // Reading this key requires explicit owner id (until end of frame). Set by ImGuiInputFlags_LockThisFrame. bool LockUntilRelease; // Reading this key requires explicit owner id (until key is released). Set by ImGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well. - ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_None; LockThisFrame = LockUntilRelease = false; } + ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_NoOwner; LockThisFrame = LockUntilRelease = false; } }; +// Extend ImGuiInputFlags_ // Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() // Don't mistake with ImGuiInputTextFlags! (which is for ImGui::InputText() function) -enum ImGuiInputFlags_ +enum ImGuiInputFlagsPrivate_ { // Flags for IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(), Shortcut() - ImGuiInputFlags_None = 0, - - // Repeat mode - ImGuiInputFlags_Repeat = 1 << 0, // Enable repeat. Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. - ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) - ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast - ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster - - // Repeat mode: Specify when repeating key pressed can be interrupted. - // In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in. - ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior. - ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut) + // - Repeat mode: Repeat rate selection + ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) + ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast + ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster + // - Repeat mode: Specify when repeating key pressed can be interrupted. + // - In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in. + ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior. + ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut) ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone = 1 << 6, // Stop repeating when released OR if keyboard mods are leaving the None state. Allows going from Mod+Key to Key by releasing Mod. - ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, // Stop repeating when released OR if any other keyboard key is pressed during the repeat - - // Flags for SetItemKeyOwner() - ImGuiInputFlags_CondHovered = 1 << 8, // Only set if item is hovered (default to both) - ImGuiInputFlags_CondActive = 1 << 9, // Only set if item is active (default to both) - ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, + ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, // Stop repeating when released OR if any other keyboard key is pressed during the repeat // Flags for SetKeyOwner(), SetItemKeyOwner() - // Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary. - ImGuiInputFlags_LockThisFrame = 1 << 10, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. - ImGuiInputFlags_LockUntilRelease = 1 << 11, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. - - // Routing policies for Shortcut() + low-level SetShortcutRouting() - // - The general idea is that several callers register interest in a shortcut, and only one owner gets it. - // Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut. - // Child1 -> call Shortcut(Ctrl+S) // When Child1 is focused, Child1 gets the shortcut (Child1 overrides Parent shortcuts) - // Child2 -> no call // When Child2 is focused, Parent gets the shortcut. - // The whole system is order independent, so if Child1 does it calls before Parent results will be identical. - // This is an important property as it facilitate working with foreign code or larger codebase. - // - Visualize registered routes in 'Metrics->Inputs' and submitted routes in 'Debug Log->InputRouting'. - // - When a policy (except for _RouteAlways *) is set, Shortcut() will register itself with SetShortcutRouting(), - // allowing the system to decide where to route the input among other route-aware calls. - // (* Using ImGuiInputFlags_RouteAlways is roughly equivalent to calling IsKeyChordPressed(key)). - // - Shortcut() uses ImGuiInputFlags_RouteFocused by default. Meaning that a Shortcut() call will register - // a route and only succeed when parent window is in the focus-stack and if no-one with a higher priority - // is claiming the same shortcut. - // - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute(). - // - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow. - // - Can select only 1 policy among all available. - ImGuiInputFlags_RouteFocused = 1 << 12, // (Default) Honor focus route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. - ImGuiInputFlags_RouteGlobalLow = 1 << 13, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority IF you need a Global priority. - ImGuiInputFlags_RouteGlobal = 1 << 14, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText will take priority over this). - ImGuiInputFlags_RouteGlobalHigh = 1 << 15, // Register route globally (higher priority: unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overriden by this) - ImGuiInputFlags_RouteAlways = 1 << 16, // Do not register route, poll keys directly. - // Routing polices: extra options - ImGuiInputFlags_RouteUnlessBgFocused= 1 << 17, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + // - Locking key away from non-input aware code. Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary. + ImGuiInputFlags_LockThisFrame = 1 << 20, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. + ImGuiInputFlags_LockUntilRelease = 1 << 21, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. + + // - Condition for SetItemKeyOwner() + ImGuiInputFlags_CondHovered = 1 << 22, // Only set if item is hovered (default to both) + ImGuiInputFlags_CondActive = 1 << 23, // Only set if item is active (default to both) + ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, // [Internal] Mask of which function support which flags ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak, ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress, ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_, ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, - ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this! + ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteActive | ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteAlways, + ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow, ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_, ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat, - ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused, + ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_, + ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_ | ImGuiInputFlags_Tooltip, ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, }; @@ -1578,6 +1578,7 @@ enum ImGuiNavMoveFlags_ ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item. ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight + ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result }; enum ImGuiNavLayer @@ -1587,6 +1588,7 @@ enum ImGuiNavLayer ImGuiNavLayer_COUNT }; +// Storage for navigation query/results struct ImGuiNavItemData { ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) @@ -1594,15 +1596,16 @@ struct ImGuiNavItemData ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags - ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. 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 + ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. ImGuiNavItemData() { Clear(); } void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } }; +// Storage for PushFocusScope() struct ImGuiFocusScopeData { ImGuiID ID; @@ -1924,6 +1927,7 @@ struct ImGuiContext ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. + float CurrentDpiScale; // Current window/viewport DpiScale ImDrawListSharedData DrawListSharedData; double Time; int FrameCount; @@ -1949,7 +1953,7 @@ struct ImGuiContext ImVector CurrentWindowStack; ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* int WindowsActiveCount; // Number of unique windows submitted by frame - ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING) + ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING). ImGuiID DebugBreakInWindow; // Set to break in Begin() call. ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. @@ -1967,10 +1971,11 @@ struct ImGuiContext ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredIdPreviousFrame; - bool HoveredIdAllowOverlap; - bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. float HoveredIdTimer; // Measure contiguous hovering time float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active + bool HoveredIdAllowOverlap; + bool HoveredIdIsDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. + bool ItemUnclipByLog; // Disable ItemAdd() clipping, essentially a memory-locality friendly copy of LogEnabled ImGuiID ActiveId; // Active widget ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame) float ActiveIdTimer; @@ -1992,9 +1997,9 @@ struct ImGuiContext ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. - // [EXPERIMENTAL] Key/Input Ownership + Shortcut Routing system + // Key/Input Ownership + Shortcut Routing system // - The idea is that instead of "eating" a given key, we can link to an owner. - // - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID. + // - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_NoOwner (== -1) or a custom ID. // - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame(). double LastKeyModsChangeTime; // Record the last time key mods changed (affect repeat delay when using shortcut logic) double LastKeyModsChangeFromNoneTime; // Record the last time key mods changed away from being 0 (affect repeat delay when using shortcut logic) @@ -2037,11 +2042,11 @@ struct ImGuiContext ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' ImGuiID NavId; // Focused item for navigation ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope) - ImVector NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain. ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem() ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0 ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat) ImGuiActivateFlags NavActivateFlags; + ImVector NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain. ImGuiID NavHighlightActivatedId; float NavHighlightActivatedTimer; ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). @@ -2082,8 +2087,8 @@ struct ImGuiContext ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) - ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab, for reconfiguration (see #4828) - ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab + ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828) + ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab on OS X) ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most! ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it. ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents @@ -2154,6 +2159,7 @@ struct ImGuiContext ImGuiInputTextDeactivatedState InputTextDeactivatedState; ImFont InputTextPasswordFont; ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types int BeginMenuDepth; int BeginComboDepth; ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets @@ -2166,13 +2172,14 @@ struct ImGuiContext ImGuiComboPreviewData ComboPreviewData; ImRect WindowResizeBorderExpectedRect; // Expected border rect, switch to relative edit if moving bool WindowResizeRelativeMode; + short ScrollbarSeekMode; // 0: relative, -1/+1: prev/next page. + float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? float SliderGrabClickOffset; float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? bool DragCurrentAccumDirty; 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? float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled() short DisabledStackSize; short LockMarkEdited; @@ -2250,7 +2257,7 @@ struct ImGuiContext Initialized = false; FontAtlasOwnedByContext = shared_font_atlas ? false : true; Font = NULL; - FontSize = FontBaseSize = 0.0f; + FontSize = FontBaseSize = CurrentDpiScale = 0.0f; IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); Time = 0.0f; FrameCount = 0; @@ -2275,8 +2282,9 @@ struct ImGuiContext DebugHookIdInfo = 0; HoveredId = HoveredIdPreviousFrame = 0; HoveredIdAllowOverlap = false; - HoveredIdDisabled = false; + HoveredIdIsDisabled = false; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; + ItemUnclipByLog = false; ActiveId = 0; ActiveIdIsAlive = 0; ActiveIdTimer = 0.0f; @@ -2338,8 +2346,10 @@ struct ImGuiContext NavTabbingDir = 0; NavTabbingCounter = 0; - ConfigNavWindowingKeyNext = ImGuiMod_Ctrl | ImGuiKey_Tab; - ConfigNavWindowingKeyPrev = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab; + // All platforms use Ctrl+Tab but Ctrl<>Super are swapped on Mac... + // FIXME: Because this value is stored, it annoyingly interfere with toggling io.ConfigMacOSXBehaviors updating this.. + ConfigNavWindowingKeyNext = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiKey_Tab); + ConfigNavWindowingKeyPrev = IO.ConfigMacOSXBehaviors ? (ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab) : (ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab); NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; @@ -2372,19 +2382,21 @@ struct ImGuiContext MouseStationaryTimer = 0.0f; TempInputId = 0; + memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue)); BeginMenuDepth = BeginComboDepth = 0; ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; ColorEditCurrentID = ColorEditSavedID = 0; ColorEditSavedHue = ColorEditSavedSat = 0.0f; ColorEditSavedColor = 0; WindowResizeRelativeMode = false; + ScrollbarSeekMode = 0; + ScrollbarClickDeltaToGrabCenter = 0.0f; SliderGrabClickOffset = 0.0f; SliderCurrentAccum = 0.0f; SliderCurrentAccumDirty = false; DragCurrentAccumDirty = false; DragCurrentAccum = 0.0f; DragSpeedDefaultRatio = 1.0f / 100.0f; - ScrollbarClickDeltaToGrabCenter = 0.0f; DisabledAlphaBackup = 0.0f; DisabledStackSize = 0; LockMarkEdited = 0; @@ -2509,12 +2521,14 @@ struct IMGUI_API ImGuiWindow ImVec2 WindowPadding; // Window padding at the time of Begin(). float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc. float WindowBorderSize; // Window border size at the time of Begin(). + float TitleBarHeight, MenuBarHeight; float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin(). float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y). float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes). int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window) + ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) ImVec2 Scroll; ImVec2 ScrollMax; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) @@ -2528,6 +2542,7 @@ struct IMGUI_API ImGuiWindow bool Collapsed; // Set when collapsing window to become only title-bar bool WantCollapseToggle; bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) + bool SkipRefresh; // [EXPERIMENTAL] Reuse previous frame drawn contents, Begin() returns false. bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool Hidden; // Do not display (== HiddenFrames*** > 0) bool IsFallbackWindow; // Set on the "Debug##Default" window. @@ -2540,7 +2555,6 @@ struct IMGUI_API ImGuiWindow short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues. short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused. - ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) ImS8 AutoFitFramesX, AutoFitFramesY; bool AutoFitOnlyGrows; ImGuiDir AutoPosLastDirection; @@ -2609,10 +2623,8 @@ struct IMGUI_API ImGuiWindow // We don't use g.FontSize because the window may be != g.CurrentWindow. ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } float CalcFontSize() const { ImGuiContext& g = *Ctx; float scale = g.FontBaseSize * FontWindowScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; } - float TitleBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; } - ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } - float MenuBarHeight() const { ImGuiContext& g = *Ctx; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; } - ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } + ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); } + ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); } }; //----------------------------------------------------------------------------- @@ -2767,13 +2779,24 @@ struct ImGuiTableColumn }; // Transient cell data stored per row. -// sizeof() ~ 6 +// sizeof() ~ 6 bytes struct ImGuiTableCellData { ImU32 BgColor; // Actual color ImGuiTableColumnIdx Column; // Column number }; +// Parameters for TableAngledHeadersRowEx() +// This may end up being refactored for more general purpose. +// sizeof() ~ 12 bytes +struct ImGuiTableHeaderData +{ + ImGuiTableColumnIdx Index; // Column index + ImU32 TextColor; + ImU32 BgColor0; + ImU32 BgColor1; +}; + // Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs. Does that means they could be moved to ImGuiTableTempData?) // sizeof() ~ 24 bytes struct ImGuiTableInstanceData @@ -2788,8 +2811,7 @@ struct ImGuiTableInstanceData ImGuiTableInstanceData() { TableInstanceID = 0; LastOuterHeight = LastTopHeadersRowHeight = LastFrozenHeight = 0.0f; HoveredRowLast = HoveredRowNext = -1; } }; -// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData -// sizeof() ~ 580 bytes + heap allocs described in TableBeginInitMemory() +// sizeof() ~ 592 bytes + heap allocs described in TableBeginInitMemory() struct IMGUI_API ImGuiTable { ImGuiID ID; @@ -2859,7 +2881,7 @@ struct IMGUI_API ImGuiTable ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs() ImGuiTableColumnIdx SortSpecsCount; ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount) - ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns (<= ColumnsCount) + ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns using fixed width (<= ColumnsCount) ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn() ImGuiTableColumnIdx AngledHeadersCount; // Count columns with angled headers ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column! @@ -2912,12 +2934,14 @@ struct IMGUI_API ImGuiTable // Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table). // - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table structure. // - We also leave out of this structure data that tend to be particularly useful for debugging/metrics. -// sizeof() ~ 120 bytes. +// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs. +// sizeof() ~ 136 bytes. struct IMGUI_API ImGuiTableTempData { int TableIndex; // Index in g.Tables.Buf[] pool float LastTimeActive; // Last timestamp this structure was used float AngledHeadersExtraWidth; // Used in EndTable() + ImVector AngledHeadersRequests; // Used in TableAngledHeadersRow() ImVec2 UserOuterSize; // outer_size.x passed to BeginTable() ImDrawListSplitter DrawSplitter; @@ -2981,7 +3005,7 @@ namespace ImGui { // Windows // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) - // If this ever crash because g.CurrentWindow is NULL it means that either + // If this ever crashes because g.CurrentWindow is NULL, it means that either: // - ImGui::NewFrame() has never been called, which is illegal. // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } @@ -2989,6 +3013,7 @@ namespace ImGui IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); + IMGUI_API void UpdateWindowSkipRefresh(ImGuiWindow* window); IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy); IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent); @@ -3014,6 +3039,9 @@ namespace ImGui IMGUI_API int FindWindowDisplayIndex(ImGuiWindow* window); IMGUI_API ImGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window); + // Windows: Idle, Refresh Policies [EXPERIMENTAL] + IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags); + // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } @@ -3029,6 +3057,7 @@ namespace ImGui // NewFrame IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs); IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); + IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void UpdateMouseMovingWindowNewFrame(); IMGUI_API void UpdateMouseMovingWindowEndFrame(); @@ -3108,6 +3137,8 @@ namespace ImGui IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx); + IMGUI_API void BeginDisabledOverrideReenable(); + IMGUI_API void EndDisabledOverrideReenable(); // Logging/Capture IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. @@ -3115,16 +3146,16 @@ namespace ImGui IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); - // Popups, Modals, Tooltips + // Childs IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags); + + // Popups, Modals + IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_window_flags); 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 bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); - IMGUI_API bool BeginTooltipHidden(); IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal(); @@ -3132,6 +3163,10 @@ namespace ImGui 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); + // Tooltips + IMGUI_API bool BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags); + IMGUI_API bool BeginTooltipHidden(); + // 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); @@ -3169,23 +3204,21 @@ namespace ImGui // Inputs // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. - inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; } - inline bool IsNamedKeyOrModKey(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super || key == ImGuiMod_Shortcut; } - inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; } - inline bool IsKeyboardKey(ImGuiKey key) { return key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END; } - inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } - inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; } - inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; } - inline bool IsModKey(ImGuiKey key) { return key >= ImGuiKey_LeftCtrl && key <= ImGuiKey_RightSuper; } - ImGuiKeyChord FixupKeyChord(ImGuiContext* ctx, ImGuiKeyChord key_chord); - inline ImGuiKey ConvertSingleModFlagToKey(ImGuiContext* ctx, ImGuiKey key) + inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; } + inline bool IsNamedKeyOrMod(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super; } + inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; } + inline bool IsKeyboardKey(ImGuiKey key) { return key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END; } + inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; } + inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; } + inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; } + inline bool IsModKey(ImGuiKey key) { return key >= ImGuiKey_LeftCtrl && key <= ImGuiKey_RightSuper; } + ImGuiKeyChord FixupKeyChord(ImGuiKeyChord key_chord); + inline ImGuiKey ConvertSingleModFlagToKey(ImGuiKey key) { - ImGuiContext& g = *ctx; if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl; if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift; if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt; if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper; - if (key == ImGuiMod_Shortcut) return (g.IO.ConfigMacOSXBehaviors ? ImGuiKey_ReservedForModSuper : ImGuiKey_ReservedForModCtrl); return key; } @@ -3205,7 +3238,7 @@ namespace ImGui // [EXPERIMENTAL] Low-Level: Key/Input Ownership // - The idea is that instead of "eating" a given input, we can link to an owner id. // - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead). - // - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID. + // - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_NoOwner (== -1) or a custom ID. // - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0). // - Input ownership is automatically released on the frame after a key is released. Therefore: // - for ownership registration happening as a result of a down/press event, the SetKeyOwner() call may be done once (common case). @@ -3213,12 +3246,12 @@ namespace ImGui // - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state. // - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step. // Please open a GitHub Issue to submit your usage scenario or if there's a use case you need solved. - IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key); - IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); - IMGUI_API void SetKeyOwnersForKeyChord(ImGuiKeyChord key, ImGuiID owner_id, ImGuiInputFlags flags = 0); - IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags = 0); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. - IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id' - inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiContext* ctx, ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(ctx, key); IM_ASSERT(IsNamedKey(key)); return &ctx->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; } + IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key); + IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); + IMGUI_API void SetKeyOwnersForKeyChord(ImGuiKeyChord key, ImGuiID owner_id, ImGuiInputFlags flags = 0); + IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags = 0); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'. + IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id' + inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiContext* ctx, ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(key); IM_ASSERT(IsNamedKey(key)); return &ctx->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; } // [EXPERIMENTAL] High-Level: Input Access functions w/ support for Key/Input Ownership // - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag. @@ -3226,32 +3259,32 @@ namespace ImGui // - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'. // Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. // - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API. - IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id); - IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat. - IMGUI_API bool IsKeyReleased(ImGuiKey key, ImGuiID owner_id); - IMGUI_API bool IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id); - IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0); - IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id); - IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button, ImGuiID owner_id); - - // [EXPERIMENTAL] Shortcut Routing - // - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super. - // ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord) - // ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord) - // ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values. - // - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy. - // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame. - // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route. - // - Multiple read sites may use the same owner id and will all get the granted route. - // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location. - // - TL;DR; - // - IsKeyChordPressed() compares mods + call IsKeyPressed() -> function has no side-effect. - // - Shortcut() submits a route then if currently can be routed calls IsKeyChordPressed() -> function has (desirable) side-effects. - IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0); - IMGUI_API void SetNextItemShortcut(ImGuiKeyChord key_chord); - IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); - IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0); // owner_id needs to be explicit and cannot be 0 - IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id); + IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id); + IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat. + IMGUI_API bool IsKeyReleased(ImGuiKey key, ImGuiID owner_id); + IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id = 0); + IMGUI_API bool IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id); + IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiInputFlags flags, ImGuiID owner_id = 0); + IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id); + IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button, ImGuiID owner_id); + + // Shortcut Testing & Routing + // - Set Shortcut() and SetNextItemShortcut() in imgui.h + // - When a policy (except for ImGuiInputFlags_RouteAlways *) is set, Shortcut() will register itself with SetShortcutRouting(), + // allowing the system to decide where to route the input among other route-aware calls. + // (* using ImGuiInputFlags_RouteAlways is roughly equivalent to calling IsKeyChordPressed(key) and bypassing route registration and check) + // - When using one of the routing option: + // - The default route is ImGuiInputFlags_RouteFocused (accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.) + // - Routes are requested given a chord (key + modifiers) and a routing policy. + // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame. + // - Each route may be granted to a single owner. When multiple requests are made we have policies to select the winning route (e.g. deep most window). + // - Multiple read sites may use the same owner id can all access the granted route. + // - When owner_id is 0 we use the current Focus Scope ID as a owner ID in order to identify our location. + // - You can chain two unrelated windows in the focus stack using SetWindowParentWindowForFocusRoute() + // e.g. if you have a tool window associated to a document, and you want document shortcuts to run when the tool is focused. + IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id); + IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id); // owner_id needs to be explicit and cannot be 0 + IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id); IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord); // [EXPERIMENTAL] Focus Scope @@ -3301,7 +3334,7 @@ namespace ImGui IMGUI_API float TableGetHeaderAngledMaxLabelWidth(); IMGUI_API void TablePushBackgroundChannel(); IMGUI_API void TablePopBackgroundChannel(); - IMGUI_API void TableAngledHeadersRowEx(float angle, float max_label_width = 0.0f); + IMGUI_API void TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count); // Tables: Internals inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } @@ -3436,7 +3469,7 @@ namespace ImGui IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); - IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format); + IMGUI_API bool DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty = NULL); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); @@ -3447,6 +3480,7 @@ namespace ImGui IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active + IMGUI_API void SetNextItemRefVal(ImGuiDataType data_type, void* p_data); // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); @@ -3478,6 +3512,7 @@ namespace ImGui IMGUI_API void DebugDrawCursorPos(ImU32 col = IM_COL32(255, 0, 0, 255)); IMGUI_API void DebugDrawLineExtents(ImU32 col = IM_COL32(255, 0, 0, 255)); IMGUI_API void DebugDrawItemRect(ImU32 col = IM_COL32(255, 0, 0, 255)); + IMGUI_API void DebugTextUnformattedWithLocateItem(const char* line_begin, const char* line_end); IMGUI_API void DebugLocateItem(ImGuiID target_id); // Call sparingly: only 1 at the same time! IMGUI_API void DebugLocateItemOnHover(ImGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time! IMGUI_API void DebugLocateItemResolveWithLastItem(); @@ -3510,6 +3545,8 @@ namespace ImGui inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89 inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89 + //inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity! + // Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister(): // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)' // (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0' @@ -3517,9 +3554,6 @@ namespace ImGui //inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) // -> pass ImGuiItemAddFlags_Inputable flag to ItemAdd() //inline void FocusableItemUnregister(ImGuiWindow* window) // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem #endif -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity! -#endif } // namespace ImGui diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_tables.cpp b/libs/bgfx/3rdparty/dear-imgui/imgui_tables.cpp index 260df1a..778d27a 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_tables.cpp +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (tables and columns code) /* @@ -24,8 +24,9 @@ Index of this file: */ // Navigating this file: -// - In Visual Studio IDE: CTRL+comma ("Edit.GoToAll") 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. +// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments. +// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments. //----------------------------------------------------------------------------- // [SECTION] Commentary @@ -227,6 +228,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked @@ -318,6 +320,12 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG IM_ASSERT(inner_width >= 0.0f); // If an outer size is specified ahead we will be able to early out when not visible. Exact clipping criteria may evolve. + // FIXME: coarse clipping because access to table data causes two issues: + // - instance numbers varying/unstable. may not be a direct problem for users, but could make outside access broken or confusing, e.g. TestEngine. + // - can't implement support for ImGuiChildFlags_ResizeY as we need to somehow pull the height data from somewhere. this also needs stable instance numbers. + // The side-effects of accessing table data on coarse clip would be: + // - always reserving the pooled ImGuiTable data ahead for a fully clipped table (minor IMHO). Also the 'outer_window_is_measuring_size' criteria may already be defeating this in some situations. + // - always performing the GetOrAddByKey() O(log N) query in g.Tables.Map[]. const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0; const ImVec2 avail_size = GetContentRegionAvail(); const ImVec2 actual_outer_size = CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f); @@ -326,6 +334,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if (use_child_window && IsClippedEx(outer_rect, 0) && !outer_window_is_measuring_size) { ItemSize(outer_rect); + ItemAdd(outer_rect, id); return false; } @@ -335,7 +344,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // Acquire storage for the table ImGuiTable* table = g.Tables.GetOrAddByKey(id); - const ImGuiTableFlags table_last_flags = table->Flags; // Acquire temporary buffers const int table_idx = g.Tables.GetIndex(table); @@ -353,6 +361,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // Initialize const int previous_frame_active = table->LastFrameActive; const int instance_no = (previous_frame_active != g.FrameCount) ? 0 : table->InstanceCurrent + 1; + const ImGuiTableFlags previous_flags = table->Flags; table->ID = id; table->Flags = flags; table->LastFrameActive = g.FrameCount; @@ -399,7 +408,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f)); // Reset scroll if we are reactivating it - if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0) + if ((previous_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0) SetNextWindowScroll(ImVec2(0.0f, 0.0f)); // Create scrolling region (without border and zero window padding) @@ -428,6 +437,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG // For non-scrolling tables, WorkRect == OuterRect == InnerRect. // But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable(). table->WorkRect = table->OuterRect = table->InnerRect = outer_rect; + table->HasScrollbarYPrev = table->HasScrollbarYCurr = false; } // Push a standardized ID for both child-using and not-child-using tables @@ -498,6 +508,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->DeclColumnsCount = table->AngledHeadersCount = 0; if (previous_frame_active + 1 < g.FrameCount) table->IsActiveIdInTable = false; + table->AngledHeadersHeight = 0.0f; temp_data->AngledHeadersExtraWidth = 0.0f; // Using opaque colors facilitate overlapping lines of the grid, otherwise we'd need to improve TableDrawBorders() @@ -511,7 +522,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. inner_window->DC.CurrentTableIdx = table_idx; - if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) + if ((previous_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0) table->IsResetDisplayOrderRequest = true; // Mark as used to avoid GC @@ -1066,6 +1077,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column. // - ClipRect.Max.x: using MaxX makes it easier for header to receive hover highlight with no discontinuity and display sorting arrow. // - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter. + const float previous_instance_work_min_x = column->WorkMinX; column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1; column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max column->ItemWidth = ImTrunc(column->WidthGiven * 0.65f); @@ -1118,8 +1130,22 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // column->WorkMinX = ImLerp(column->WorkMinX, ImMax(column->StartX, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f); // Reset content width variables - column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX; - column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX; + if (table->InstanceCurrent == 0) + { + column->ContentMaxXFrozen = column->WorkMinX; + column->ContentMaxXUnfrozen = column->WorkMinX; + column->ContentMaxXHeadersUsed = column->WorkMinX; + column->ContentMaxXHeadersIdeal = column->WorkMinX; + } + else + { + // As we store an absolute value to make per-cell updates faster, we need to offset values used for width computation. + const float offset_from_previous_instance = column->WorkMinX - previous_instance_work_min_x; + column->ContentMaxXFrozen += offset_from_previous_instance; + column->ContentMaxXUnfrozen += offset_from_previous_instance; + column->ContentMaxXHeadersUsed += offset_from_previous_instance; + column->ContentMaxXHeadersIdeal += offset_from_previous_instance; + } // Don't decrement auto-fit counters until container window got a chance to submit its items if (table->HostSkipItems == false) @@ -1238,9 +1264,9 @@ void ImGui::TableUpdateBorders(ImGuiTable* table) // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). // Actual columns highlight/render will be performed in EndTable() and not be affected. ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); - const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS; + const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale); const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight; - const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight); + const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight); const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight; for (int order_n = 0; order_n < table->ColumnsCount; order_n++) @@ -1415,7 +1441,7 @@ void ImGui::EndTable() if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted) { ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; - const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); + const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale)); const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); table->ResizedColumnNextWidth = new_width; } @@ -1444,7 +1470,10 @@ void ImGui::EndTable() // CursorPosPrevLine and CursorMaxPos manually. That should be a more general layout feature, see same problem e.g. #3414) if (inner_window != outer_window) { + short backup_nav_layers_active_mask = inner_window->DC.NavLayersActiveMask; + inner_window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; // So empty table don't appear to navigate differently. EndChild(); + inner_window->DC.NavLayersActiveMask = backup_nav_layers_active_mask; } else { @@ -1462,9 +1491,13 @@ void ImGui::EndTable() } else if (temp_data->UserOuterSize.x <= 0.0f) { - const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f); - outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x); - outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth)); + // Some references for this: #7651 + tests "table_reported_size", "table_reported_size_outer" equivalent Y block + // - Checking for ImGuiTableFlags_ScrollX/ScrollY flag makes us a frame ahead when disabling those flags. + // - FIXME-TABLE: Would make sense to pre-compute expected scrollbar visibility/sizes to generally save a frame of feedback. + const float inner_content_max_x = table->OuterRect.Min.x + table->ColumnsAutoFitWidth; // Slightly misleading name but used for code symmetry with inner_content_max_y + const float decoration_size = table->TempData->AngledHeadersExtraWidth + ((table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.x : 0.0f); + outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, inner_content_max_x + decoration_size - temp_data->UserOuterSize.x); + outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, inner_content_max_x + decoration_size)); } else { @@ -1472,9 +1505,9 @@ void ImGui::EndTable() } if (temp_data->UserOuterSize.y <= 0.0f) { - const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f; + const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.y : 0.0f; outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y); - outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y)); + outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y + decoration_size)); } else { @@ -1890,7 +1923,7 @@ void ImGui::TableEndRow(ImGuiTable* table) if (is_visible) { // Update data for TableGetHoveredRow() - if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2) + if (table->HoveredColumnBody != -1 && g.IO.MousePos.y >= bg_y1 && g.IO.MousePos.y < bg_y2 && table_instance->HoveredRowNext < 0) table_instance->HoveredRowNext = table->CurrentRow; // Decide of background color for the row @@ -1945,7 +1978,8 @@ void ImGui::TableEndRow(ImGuiTable* table) cell_bg_rect.ClipWith(table->BgClipRect); cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX); - window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); + if (cell_bg_rect.Min.y < cell_bg_rect.Max.y) + window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); } } @@ -2766,7 +2800,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs() static inline ImGuiSortDirection TableGetColumnAvailSortDirection(ImGuiTableColumn* column, int n) { IM_ASSERT(n < column->SortDirectionsAvailCount); - return (column->SortDirectionsAvailList >> (n << 1)) & 0x03; + return (ImGuiSortDirection)((column->SortDirectionsAvailList >> (n << 1)) & 0x03); } // Fix sort direction if currently set on a value which is unavailable (e.g. activating NoSortAscending/NoSortDescending) @@ -2907,6 +2941,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table) } // Write output + // May be able to move all SortSpecs data from table (48 bytes) to ImGuiTableTempData if we decide to write it back on every BeginTable() ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data; if (dirty && sort_specs != NULL) for (int column_n = 0; column_n < table->ColumnsCount; column_n++) @@ -2919,7 +2954,7 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table) sort_spec->ColumnUserID = column->UserID; sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n; sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder; - sort_spec->SortDirection = column->SortDirection; + sort_spec->SortDirection = (ImGuiSortDirection)column->SortDirection; } table->SortSpecs.Specs = sort_specs; @@ -2967,7 +3002,7 @@ float ImGui::TableGetHeaderAngledMaxLabelWidth() // [Public] This is a helper to output TableHeader() calls based on the column names declared in TableSetupColumn(). // The intent is that advanced users willing to create customized headers would not need to use this helper -// and can create their own! For example: TableHeader() may be preceeded by Checkbox() or other custom widgets. +// and can create their own! For example: TableHeader() may be preceded by Checkbox() or other custom widgets. // See 'Demo->Tables->Custom headers' for a demonstration of implementing a custom version of this. // This code is constructed to not make much use of internal functions, as it is intended to be a template to copy. // FIXME-TABLE: TableOpenContextMenu() and TableGetHeaderRowHeight() are not public. @@ -3153,15 +3188,43 @@ void ImGui::TableHeader(const char* label) } // Unlike TableHeadersRow() it is not expected that you can reimplement or customize this with custom widgets. -// FIXME: highlight without ImGuiTableFlags_HighlightHoveredColumn // FIXME: No hit-testing/button on the angled header. void ImGui::TableAngledHeadersRow() { ImGuiContext& g = *GImGui; - TableAngledHeadersRowEx(g.Style.TableAngledHeadersAngle, 0.0f); + ImGuiTable* table = g.CurrentTable; + ImGuiTableTempData* temp_data = table->TempData; + temp_data->AngledHeadersRequests.resize(0); + temp_data->AngledHeadersRequests.reserve(table->ColumnsEnabledCount); + + // Which column needs highlight? + const ImGuiID row_id = GetID("##AngledHeaders"); + ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); + int highlight_column_n = table->HighlightColumnHeader; + if (highlight_column_n == -1 && table->HoveredColumnBody != -1) + if (table_instance->HoveredRowLast == 0 && table->HoveredColumnBorder == -1 && (g.ActiveId == 0 || g.ActiveId == row_id || (table->IsActiveIdInTable || g.DragDropActive))) + highlight_column_n = table->HoveredColumnBody; + + // Build up request + ImU32 col_header_bg = GetColorU32(ImGuiCol_TableHeaderBg); + ImU32 col_text = GetColorU32(ImGuiCol_Text); + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + if (IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) + { + const int column_n = table->DisplayOrderToIndex[order_n]; + ImGuiTableColumn* column = &table->Columns[column_n]; + if ((column->Flags & ImGuiTableColumnFlags_AngledHeader) == 0) // Note: can't rely on ImGuiTableColumnFlags_IsVisible test here. + continue; + ImGuiTableHeaderData request = { (ImGuiTableColumnIdx)column_n, col_text, col_header_bg, (column_n == highlight_column_n) ? GetColorU32(ImGuiCol_Header) : 0 }; + temp_data->AngledHeadersRequests.push_back(request); + } + + // Render row + TableAngledHeadersRowEx(row_id, g.Style.TableAngledHeadersAngle, 0.0f, temp_data->AngledHeadersRequests.Data, temp_data->AngledHeadersRequests.Size); } -void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) +// Important: data must be fed left to right +void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count) { ImGuiContext& g = *GImGui; ImGuiTable* table = g.CurrentTable; @@ -3185,7 +3248,7 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) // Calculate our base metrics and set angled headers data _before_ the first call to TableNextRow() // FIXME-STYLE: Would it be better for user to submit 'max_label_width' or 'row_height' ? One can be derived from the other. const float header_height = g.FontSize + g.Style.CellPadding.x * 2.0f; - const float row_height = ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y); + const float row_height = ImTrunc(ImFabs(ImRotate(ImVec2(max_label_width, flip_label ? +header_height : -header_height), cos_a, sin_a).y)); table->AngledHeadersHeight = row_height; table->AngledHeadersSlope = (sin_a != 0.0f) ? (cos_a / sin_a) : 0.0f; const ImVec2 header_angled_vector = unit_right * (row_height / -sin_a); // vector from bottom-left to top-left, and from bottom-right to top-right @@ -3203,28 +3266,22 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) draw_list->AddRectFilled(ImVec2(table->BgClipRect.Min.x, row_r.Min.y), ImVec2(table->BgClipRect.Max.x, row_r.Max.y), GetColorU32(ImGuiCol_TableHeaderBg, 0.25f)); // FIXME-STYLE: Change row background with an arbitrary color. PushClipRect(ImVec2(clip_rect_min_x, table->BgClipRect.Min.y), table->BgClipRect.Max, true); // Span all columns - const ImGuiID row_id = GetID("##AngledHeaders"); ButtonBehavior(row_r, row_id, NULL, NULL); KeepAliveID(row_id); - ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); - int highlight_column_n = table->HighlightColumnHeader; - if (highlight_column_n == -1 && table->HoveredColumnBody != -1) - if (table_instance->HoveredRowLast == 0 && table->HoveredColumnBorder == -1 && (g.ActiveId == 0 || g.ActiveId == row_id || (table->IsActiveIdInTable || g.DragDropActive))) - highlight_column_n = table->HoveredColumnBody; + const float ascent_scaled = g.Font->Ascent * (g.FontSize / g.Font->FontSize); // FIXME: Standardize those scaling factors better + const float line_off_for_ascent_x = (ImMax((g.FontSize - ascent_scaled) * 0.5f, 0.0f) / -sin_a) * (flip_label ? -1.0f : 1.0f); + const ImVec2 padding = g.Style.CellPadding; // We will always use swapped component + const ImVec2 align = g.Style.TableAngledHeadersTextAlign; // Draw background and labels in first pass, then all borders. float max_x = 0.0f; - ImVec2 padding = g.Style.CellPadding; // We will always use swapped component for (int pass = 0; pass < 2; pass++) - for (int order_n = 0; order_n < table->ColumnsCount; order_n++) + for (int order_n = 0; order_n < data_count; order_n++) { - if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n)) - continue; - const int column_n = table->DisplayOrderToIndex[order_n]; + const ImGuiTableHeaderData* request = &data[order_n]; + const int column_n = request->Index; ImGuiTableColumn* column = &table->Columns[column_n]; - if ((column->Flags & ImGuiTableColumnFlags_AngledHeader) == 0) // Note: can't rely on ImGuiTableColumnFlags_IsVisible test here. - continue; ImVec2 bg_shape[4]; bg_shape[0] = ImVec2(column->MaxX, row_r.Max.y); @@ -3234,9 +3291,8 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) if (pass == 0) { // Draw shape - draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_TableHeaderBg)); - if (column_n == highlight_column_n) - draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], GetColorU32(ImGuiCol_Header)); // Highlight on hover + draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], request->BgColor0); + draw_list->AddQuadFilled(bg_shape[0], bg_shape[1], bg_shape[2], bg_shape[3], request->BgColor1); // Optional highlight max_x = ImMax(max_x, bg_shape[3].x); // Draw label @@ -3244,8 +3300,17 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) // - Handle multiple lines manually, as we want each lines to follow on the horizontal border, rather than see a whole block rotated. const char* label_name = TableGetColumnName(table, column_n); const char* label_name_end = FindRenderedTextEnd(label_name); - const float line_off_step_x = g.FontSize / -sin_a; - float line_off_curr_x = 0.0f; + const float line_off_step_x = (g.FontSize / -sin_a); + const int label_lines = ImTextCountLines(label_name, label_name_end); + + // Left<>Right alignment + float line_off_curr_x = flip_label ? (label_lines - 1) * line_off_step_x : 0.0f; + float line_off_for_align_x = ImMax((((column->MaxX - column->MinX) - padding.x * 2.0f) - (label_lines * line_off_step_x)), 0.0f) * align.x; + line_off_curr_x += line_off_for_align_x - line_off_for_ascent_x; + + // Register header width + column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(label_lines * line_off_step_x - line_off_for_align_x); + while (label_name < label_name_end) { const char* label_name_eol = strchr(label_name, '\n'); @@ -3254,26 +3319,30 @@ void ImGui::TableAngledHeadersRowEx(float angle, float max_label_width) // FIXME: Individual line clipping for right-most column is broken for negative angles. ImVec2 label_size = CalcTextSize(label_name, label_name_eol); - float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symetrical but hide more text. + float clip_width = max_label_width - padding.y; // Using padding.y*2.0f would be symmetrical but hide more text. float clip_height = ImMin(label_size.y, column->ClipRect.Max.x - column->WorkMinX - line_off_curr_x); ImRect clip_r(window->ClipRect.Min, window->ClipRect.Min + ImVec2(clip_width, clip_height)); int vtx_idx_begin = draw_list->_VtxCurrentIdx; + PushStyleColor(ImGuiCol_Text, request->TextColor); RenderTextEllipsis(draw_list, clip_r.Min, clip_r.Max, clip_r.Max.x, clip_r.Max.x, label_name, label_name_eol, &label_size); + PopStyleColor(); int vtx_idx_end = draw_list->_VtxCurrentIdx; + // Up<>Down alignment + const float available_space = ImMax(clip_width - label_size.x + ImAbs(padding.x * cos_a) * 2.0f - ImAbs(padding.y * sin_a) * 2.0f, 0.0f); + const float vertical_offset = available_space * align.y * (flip_label ? -1.0f : 1.0f); + // Rotate and offset label - ImVec2 pivot_in = ImVec2(window->ClipRect.Min.x, window->ClipRect.Min.y + label_size.y); + ImVec2 pivot_in = ImVec2(window->ClipRect.Min.x - vertical_offset, window->ClipRect.Min.y + label_size.y); ImVec2 pivot_out = ImVec2(column->WorkMinX, row_r.Max.y); - line_off_curr_x += line_off_step_x; + line_off_curr_x += flip_label ? -line_off_step_x : line_off_step_x; pivot_out += unit_right * padding.y; if (flip_label) pivot_out += unit_right * (clip_width - ImMax(0.0f, clip_width - label_size.x)); - pivot_out.x += flip_label ? line_off_curr_x - line_off_step_x : line_off_curr_x; + pivot_out.x += flip_label ? line_off_curr_x + line_off_step_x : line_off_curr_x; ShadeVertsTransformPos(draw_list, vtx_idx_begin, vtx_idx_end, pivot_in, label_cos_a, label_sin_a, pivot_out); // Rotate and offset - //if (g.IO.KeyShift) { ImDrawList* fg_dl = GetForegroundDrawList(); vtx_idx_begin = fg_dl->_VtxCurrentIdx; fg_dl->AddRect(clip_r.Min, clip_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 2.0f); ShadeVertsTransformPos(fg_dl, vtx_idx_begin, fg_dl->_VtxCurrentIdx, pivot_in, label_cos_a, label_sin_a, pivot_out); } + //if (g.IO.KeyShift) { ImDrawList* fg_dl = GetForegroundDrawList(); vtx_idx_begin = fg_dl->_VtxCurrentIdx; fg_dl->AddRect(clip_r.Min, clip_r.Max, IM_COL32(0, 255, 0, 255), 0.0f, 0, 1.0f); ShadeVertsTransformPos(fg_dl, vtx_idx_begin, fg_dl->_VtxCurrentIdx, pivot_in, label_cos_a, label_sin_a, pivot_out); } - // Register header width - column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX + ImCeil(line_off_curr_x); label_name = label_name_eol + 1; } } @@ -3988,7 +4057,7 @@ float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offse return offset / (columns->OffMaxX - columns->OffMinX); } -static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f; +static const float COLUMNS_HIT_RECT_HALF_THICKNESS = 4.0f; static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) { @@ -3999,7 +4068,7 @@ static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); - float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x; + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale) - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); @@ -4314,7 +4383,7 @@ void ImGui::EndColumns() ImGuiOldColumnData* column = &columns->Columns[n]; float x = window->Pos.x + GetColumnOffset(n); const ImGuiID column_id = columns->ID + ImGuiID(n); - const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; + const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale); const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav)) continue; diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_user.h b/libs/bgfx/3rdparty/dear-imgui/imgui_user.h index e181995..b6b57aa 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_user.h +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_user.h @@ -48,5 +48,4 @@ namespace ImGui #include "widgets/file_list.h" #include "widgets/gizmo.h" #include "widgets/markdown.h" -#include "widgets/memory_editor.h" #include "widgets/range_slider.h" diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_user.inl b/libs/bgfx/3rdparty/dear-imgui/imgui_user.inl index 1ef1902..7cc28b4 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_user.inl +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_user.inl @@ -77,5 +77,4 @@ namespace ImGui #include "widgets/file_list.inl" #include "widgets/gizmo.inl" #include "widgets/markdown.inl" -#include "widgets/memory_editor.inl" #include "widgets/range_slider.inl" diff --git a/libs/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp b/libs/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp index feb814d..4d83d9c 100644 --- a/libs/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp +++ b/libs/bgfx/3rdparty/dear-imgui/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.4 +// dear imgui, v1.90.9 WIP // (widgets code) /* @@ -75,6 +75,7 @@ Index of this file: #pragma clang diagnostic ignored "-Wenum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision +#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked @@ -122,9 +123,9 @@ static const ImU64 IM_U64_MAX = (2ULL * 9223372036854775807LL + 1); //------------------------------------------------------------------------- // For InputTextEx() -static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source); -static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); -static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); +static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard = false); +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); +static ImVec2 InputTextCalcTextSizeW(ImGuiContext* ctx, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); //------------------------------------------------------------------------- // [SECTION] Widgets: Text, etc. @@ -487,7 +488,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool // Default only reacts to left mouse button if ((flags & ImGuiButtonFlags_MouseButtonMask_) == 0) - flags |= ImGuiButtonFlags_MouseButtonDefault_; + flags |= ImGuiButtonFlags_MouseButtonLeft; // Default behavior requires click + release inside bounding box if ((flags & ImGuiButtonFlags_PressedOnMask_) == 0) @@ -508,7 +509,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool #ifdef IMGUI_ENABLE_TEST_ENGINE // Alternate registration spot, for when caller didn't use ItemAdd() - if (id != 0 && g.LastItemData.ID != id) + if (g.LastItemData.ID != id) IMGUI_TEST_ENGINE_ITEM_ADD(id, bb, NULL); #endif @@ -536,6 +537,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; if (hovered) { + IM_ASSERT(id != 0); // Lazily check inside rare path. + // Poll mouse buttons // - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId. // - Technically we only need some values in one code path, but since this is gated by hovered test this is fine. @@ -544,7 +547,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool for (int button = 0; button < 3; button++) if (flags & (ImGuiButtonFlags_MouseButtonLeft << button)) // Handle ImGuiButtonFlags_MouseButtonRight and ImGuiButtonFlags_MouseButtonMiddle here. { - if (IsMouseClicked(button, test_owner_id) && mouse_button_clicked == -1) { mouse_button_clicked = button; } + if (IsMouseClicked(button, ImGuiInputFlags_None, test_owner_id) && mouse_button_clicked == -1) { mouse_button_clicked = button; } if (IsMouseReleased(button, test_owner_id) && mouse_button_released == -1) { mouse_button_released = button; } } @@ -592,7 +595,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. if (g.ActiveId == id && (item_flags & ImGuiItemFlags_ButtonRepeat)) - if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, test_owner_id, ImGuiInputFlags_Repeat)) + if (g.IO.MouseDownDuration[g.ActiveIdMouseButton] > 0.0f && IsMouseClicked(g.ActiveIdMouseButton, ImGuiInputFlags_Repeat, test_owner_id)) pressed = true; } @@ -913,10 +916,10 @@ void ImGui::Scrollbar(ImGuiAxis axis) if (!window->ScrollbarX) rounding_corners |= ImDrawFlags_RoundCornersBottomRight; } - float size_avail = window->InnerRect.Max[axis] - window->InnerRect.Min[axis]; + float size_visible = window->InnerRect.Max[axis] - window->InnerRect.Min[axis]; float size_contents = window->ContentSize[axis] + window->WindowPadding[axis] * 2.0f; ImS64 scroll = (ImS64)window->Scroll[axis]; - ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_avail, (ImS64)size_contents, rounding_corners); + ScrollbarEx(bb, id, axis, &scroll, (ImS64)size_visible, (ImS64)size_contents, rounding_corners); window->Scroll[axis] = (float)scroll; } @@ -926,7 +929,7 @@ void ImGui::Scrollbar(ImGuiAxis axis) // - We store values as normalized ratio and in a form that allows the window content to change while we are holding on a scrollbar // - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. // Still, the code should probably be made simpler.. -bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_avail_v, ImS64 size_contents_v, ImDrawFlags flags) +bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 size_visible_v, ImS64 size_contents_v, ImDrawFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -956,9 +959,9 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) // But we maintain a minimum size in pixel to allow for the user to still aim inside. - IM_ASSERT(ImMax(size_contents_v, size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. - const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_avail_v), (ImS64)1); - const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_avail_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v); + IM_ASSERT(ImMax(size_contents_v, size_visible_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. + const ImS64 win_size_v = ImMax(ImMax(size_contents_v, size_visible_v), (ImS64)1); + const float grab_h_pixels = ImClamp(scrollbar_size_v * ((float)size_visible_v / (float)win_size_v), style.GrabMinSize, scrollbar_size_v); const float grab_h_norm = grab_h_pixels / scrollbar_size_v; // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). @@ -967,7 +970,7 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 ItemAdd(bb_frame, id, NULL, ImGuiItemFlags_NoNav); ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); - const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_avail_v); + const ImS64 scroll_max = ImMax((ImS64)1, size_contents_v - size_visible_v); float scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; // Grab position in normalized space if (held && allow_interaction && grab_h_norm < 1.0f) @@ -978,29 +981,39 @@ bool ImGui::ScrollbarEx(const ImRect& bb_frame, ImGuiID id, ImGuiAxis axis, ImS6 // Click position in scrollbar normalized space (0.0f->1.0f) const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); - bool seek_absolute = false; + const int held_dir = (clicked_v_norm < grab_v_norm) ? -1 : (clicked_v_norm > grab_v_norm + grab_h_norm) ? +1 : 0; if (g.ActiveIdIsJustActivated) { // On initial click calculate the distance between mouse and the center of the grab - seek_absolute = (clicked_v_norm < grab_v_norm || clicked_v_norm > grab_v_norm + grab_h_norm); - if (seek_absolute) - g.ScrollbarClickDeltaToGrabCenter = 0.0f; - else - g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + g.ScrollbarSeekMode = (short)held_dir; + g.ScrollbarClickDeltaToGrabCenter = (g.ScrollbarSeekMode == 0.0f) ? clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f : 0.0f; } // Apply scroll (p_scroll_v will generally point on one member of window->Scroll) // It is ok to modify Scroll here because we are being called in Begin() after the calculation of ContentSize and before setting up our starting position - const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); - *p_scroll_v = (ImS64)(scroll_v_norm * scroll_max); + if (g.ScrollbarSeekMode == 0) + { + // Absolute seeking + const float scroll_v_norm = ImSaturate((clicked_v_norm - g.ScrollbarClickDeltaToGrabCenter - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); + *p_scroll_v = (ImS64)(scroll_v_norm * scroll_max); + } + else + { + // Page by page + if (IsMouseClicked(ImGuiMouseButton_Left, ImGuiInputFlags_Repeat) && held_dir == g.ScrollbarSeekMode) + { + float page_dir = (g.ScrollbarSeekMode > 0.0f) ? +1.0f : -1.0f; + *p_scroll_v = ImClamp(*p_scroll_v + (ImS64)(page_dir * size_visible_v), (ImS64)0, scroll_max); + } + } // Update values for rendering scroll_ratio = ImSaturate((float)*p_scroll_v / (float)scroll_max); grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; - // Update distance to grab now that we have seeked and saturated - if (seek_absolute) - g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + // Update distance to grab now that we have seek'ed and saturated + //if (seek_absolute) + // g.ScrollbarClickDeltaToGrabCenter = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; } // Render @@ -1288,24 +1301,47 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over if (!ItemAdd(bb, 0)) return; + // Fraction < 0.0f will display an indeterminate progress bar animation + // The value must be animated along with time, so e.g. passing '-1.0f * ImGui::GetTime()' as fraction works. + const bool is_indeterminate = (fraction < 0.0f); + if (!is_indeterminate) + fraction = ImSaturate(fraction); + + // Out of courtesy we accept a NaN fraction without crashing + float fill_n0 = 0.0f; + float fill_n1 = (fraction == fraction) ? fraction : 0.0f; + + if (is_indeterminate) + { + const float fill_width_n = 0.2f; + fill_n0 = ImFmod(-fraction, 1.0f) * (1.0f + fill_width_n) - fill_width_n; + fill_n1 = ImSaturate(fill_n0 + fill_width_n); + fill_n0 = ImSaturate(fill_n0); + } + // Render - fraction = ImSaturate(fraction); RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); - const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); - RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); + RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_n0, fill_n1, style.FrameRounding); // Default displaying the fraction as percentage string, but user can override it + // Don't display text for indeterminate bars by default char overlay_buf[32]; - if (!overlay) + if (!is_indeterminate || overlay != NULL) { - ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); - overlay = overlay_buf; - } + if (!overlay) + { + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); + overlay = overlay_buf; + } - ImVec2 overlay_size = CalcTextSize(overlay, NULL); - if (overlay_size.x > 0.0f) - RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); + ImVec2 overlay_size = CalcTextSize(overlay, NULL); + if (overlay_size.x > 0.0f) + { + float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x; + RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); + } + } } void ImGui::Bullet() @@ -1916,28 +1952,30 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo return false; // Display items - // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) bool value_changed = false; - for (int i = 0; i < items_count; i++) - { - const char* item_text = getter(user_data, i); - if (item_text == NULL) - item_text = "*Unknown item*"; - - PushID(i); - const bool item_selected = (i == *current_item); - if (Selectable(item_text, item_selected) && *current_item != i) + ImGuiListClipper clipper; + clipper.Begin(items_count); + clipper.IncludeItemByIndex(*current_item); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { - value_changed = true; - *current_item = i; + const char* item_text = getter(user_data, i); + if (item_text == NULL) + item_text = "*Unknown item*"; + + PushID(i); + const bool item_selected = (i == *current_item); + if (Selectable(item_text, item_selected) && *current_item != i) + { + value_changed = true; + *current_item = i; + } + if (item_selected) + SetItemDefaultFocus(); + PopID(); } - if (item_selected) - SetItemDefaultFocus(); - PopID(); - } EndCombo(); - if (value_changed) MarkItemEdited(g.LastItemData.ID); @@ -2103,17 +2141,24 @@ void ImGui::DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const // User can input math operators (e.g. +100) to edit a numerical values. // NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. -bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format) +bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void* p_data, const char* format, void* p_data_when_empty) { + // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. + const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); + ImGuiDataTypeStorage data_backup; + memcpy(&data_backup, p_data, type_info->Size); + while (ImCharIsBlankA(*buf)) buf++; if (!buf[0]) + { + if (p_data_when_empty != NULL) + { + memcpy(p_data, p_data_when_empty, type_info->Size); + return memcmp(&data_backup, p_data, type_info->Size) != 0; + } return false; - - // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. - const ImGuiDataTypeInfo* type_info = DataTypeGetInfo(data_type); - ImGuiDataTypeTempStorage data_backup; - memcpy(&data_backup, p_data, type_info->Size); + } // Sanitize format // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf @@ -2283,7 +2328,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); - const float tweak_factor = tweak_slow ? 1.0f / 1.0f : tweak_fast ? 10.0f : 1.0f; + const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f; adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } @@ -2442,7 +2487,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data, if (!temp_input_is_active) { // Tabbing or CTRL-clicking on Drag turns it into an InputText - const bool clicked = hovered && IsMouseClicked(0, id); + const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id); const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id)); const bool make_active = (clicked || double_clicked || g.NavActivateId == id); if (make_active && (clicked || double_clicked)) @@ -3048,7 +3093,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat if (!temp_input_is_active) { // Tabbing or CTRL-clicking on Slider turns it into an input box - const bool clicked = hovered && IsMouseClicked(0, id); + const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id); const bool make_active = (clicked || g.NavActivateId == id); if (make_active && clicked) SetKeyOwner(ImGuiKey_MouseLeft, id); @@ -3210,7 +3255,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d format = DataTypeGetInfo(data_type)->PrintFmt; const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); - const bool clicked = hovered && IsMouseClicked(0, id); + const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id); if (clicked || g.NavActivateId == id) { if (clicked) @@ -3441,18 +3486,18 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, p_data, format); ImStrTrimBlanks(data_buf); - ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; + ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint; bool value_changed = false; if (TempInputText(bb, id, label, data_buf, IM_ARRAYSIZE(data_buf), flags)) { // Backup old value size_t data_type_size = type_info->Size; - ImGuiDataTypeTempStorage data_backup; + ImGuiDataTypeStorage data_backup; memcpy(&data_backup, p_data, data_type_size); // Apply new value (or operations) then clamp - DataTypeApplyFromText(data_buf, data_type, p_data, format); + DataTypeApplyFromText(data_buf, data_type, p_data, format, NULL); if (p_clamp_min || p_clamp_max) { if (p_clamp_min && p_clamp_max && DataTypeCompare(data_type, p_clamp_min, p_clamp_max) > 0) @@ -3468,6 +3513,13 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG return value_changed; } +void ImGui::SetNextItemRefVal(ImGuiDataType data_type, void* p_data) +{ + ImGuiContext& g = *GImGui; + g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasRefVal; + memcpy(&g.NextItemData.RefVal, p_data, DataTypeGetInfo(data_type)->Size); +} + // Note: p_data, p_step, p_step_fast are _pointers_ to a memory address holding the data. For an Input widget, p_step and p_step_fast are optional. // Read code of e.g. InputFloat(), InputInt() etc. or examples in 'Demo->Widgets->Data Types' to understand how to use this function directly. bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data, const void* p_step, const void* p_step_fast, const char* format, ImGuiInputTextFlags flags) @@ -3482,16 +3534,22 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data if (format == NULL) format = DataTypeGetInfo(data_type)->PrintFmt; + void* p_data_default = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue; + char buf[64]; - DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); + if ((flags & ImGuiInputTextFlags_DisplayEmptyRefVal) && DataTypeCompare(data_type, p_data, p_data_default) == 0) + buf[0] = 0; + else + DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, p_data, format); flags |= ImGuiInputTextFlags_AutoSelectAll | (ImGuiInputTextFlags)ImGuiInputTextFlags_NoMarkEdited; // We call MarkItemEdited() ourselves by comparing the actual data rather than the string. + flags |= (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint; bool value_changed = false; if (p_step == NULL) { if (InputText(label, buf, IM_ARRAYSIZE(buf), flags)) - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); } else { @@ -3501,7 +3559,7 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data PushID(label); SetNextItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); if (InputText("", buf, IM_ARRAYSIZE(buf), flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyFromText(buf, data_type, p_data, format); + value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL); IMGUI_TEST_ENGINE_ITEM_INFO(g.LastItemData.ID, label, g.LastItemData.StatusFlags | ImGuiItemStatusFlags_Inputable); // Step buttons @@ -3931,9 +3989,8 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons } // Return false to discard a character. -static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, ImGuiInputSource input_source) +static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data, bool input_source_is_clipboard) { - IM_ASSERT(input_source == ImGuiInputSource_Keyboard || input_source == ImGuiInputSource_Clipboard); unsigned int c = *p_char; // Filter non-printable (NB: isprint is unreliable! see #2467) @@ -3948,7 +4005,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im apply_named_filters = false; // Override named filters below so newline and tabs can still be inserted. } - if (input_source != ImGuiInputSource_Clipboard) + if (input_source_is_clipboard == false) { // We ignore Ascii representation of delete (emitted from Backspace on OSX, see #2578, #2817) if (c == 127) @@ -3964,7 +4021,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im return false; // Generic named filters - if (apply_named_filters && (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 | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint))) { // The libc allows overriding locale, with e.g. 'setlocale(LC_NUMERIC, "de_DE.UTF-8");' which affect the output/input of printf/scanf to use e.g. ',' instead of '.'. // The standard mandate that programs starts in the "C" locale where the decimal point is '.'. @@ -3974,7 +4031,7 @@ static bool InputTextFilterCharacter(ImGuiContext* ctx, unsigned int* p_char, Im // Users of non-default decimal point (in particular ',') may be affected by word-selection logic (is_word_boundary_from_right/is_word_boundary_from_left) functions. ImGuiContext& g = *ctx; const unsigned c_decimal_point = (unsigned int)g.IO.PlatformLocaleDecimalPoint; - if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsScientific)) + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsScientific | (ImGuiInputTextFlags)ImGuiInputTextFlags_LocalizeDecimalPoint)) if (c == '.' || c == ',') c = c_decimal_point; @@ -4298,6 +4355,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ SetKeyOwner(ImGuiKey_PageUp, id); SetKeyOwner(ImGuiKey_PageDown, id); } + // FIXME: May be a problem to always steal Alt on OSX, would ideally still allow an uninterrupted Alt down-up to toggle menu if (is_osx) SetKeyOwner(ImGuiMod_Alt, id); } @@ -4430,15 +4488,15 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // (For Tab and Enter: Win32/SFML/Allegro are sending both keys and chars, GLFW and SDL are only sending keys. For Space they all send all threes) if ((flags & ImGuiInputTextFlags_AllowTabInput) && !is_readonly) { - if (Shortcut(ImGuiKey_Tab, id, ImGuiInputFlags_Repeat)) + if (Shortcut(ImGuiKey_Tab, ImGuiInputFlags_Repeat, id)) { unsigned int c = '\t'; // Insert TAB - if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data)) state->OnKeyPressed((int)c); } // FIXME: Implement Shift+Tab /* - if (Shortcut(ImGuiKey_Tab | ImGuiMod_Shift, id, ImGuiInputFlags_Repeat)) + if (Shortcut(ImGuiKey_Tab | ImGuiMod_Shift, ImGuiInputFlags_Repeat, id)) { } */ @@ -4446,7 +4504,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Process regular text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. - const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); + const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeyCtrl); if (io.InputQueueCharacters.Size > 0) { if (!ignore_char_inputs && !is_readonly && !input_requested_by_nav) @@ -4456,7 +4514,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ unsigned int c = (unsigned int)io.InputQueueCharacters[n]; if (c == '\t') // Skip Tab, see above. continue; - if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data)) state->OnKeyPressed((int)c); } @@ -4476,25 +4534,26 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl - const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_startend_key_down = is_osx && io.KeyCtrl && !io.KeySuper && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End // Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: formet would be handled by InputText) // Otherwise we could simply assume that we own the keys as we are active. const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat; - const bool is_cut = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_X, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, id, f_repeat)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); - const bool is_copy = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_C, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, id)) && !is_password && (!is_multiline || state->HasSelection()); - const bool is_paste = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_V, id, f_repeat) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, id, f_repeat)) && !is_readonly; - const bool is_undo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Z, id, f_repeat)) && !is_readonly && is_undoable; - const bool is_redo = (Shortcut(ImGuiMod_Shortcut | ImGuiKey_Y, id, f_repeat) || (is_osx && Shortcut(ImGuiMod_Shortcut | ImGuiMod_Shift | ImGuiKey_Z, id, f_repeat))) && !is_readonly && is_undoable; - const bool is_select_all = Shortcut(ImGuiMod_Shortcut | ImGuiKey_A, id); + const bool is_cut = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_X, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, f_repeat, id)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection()); + const bool is_copy = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_C, 0, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_Insert, 0, id)) && !is_password && (!is_multiline || state->HasSelection()); + const bool is_paste = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_V, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Insert, f_repeat, id)) && !is_readonly; + const bool is_undo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Z, f_repeat, id)) && !is_readonly && is_undoable; + const bool is_redo = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_Y, f_repeat, id) || (is_osx && Shortcut(ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Z, f_repeat, id))) && !is_readonly && is_undoable; + const bool is_select_all = Shortcut(ImGuiMod_Ctrl | ImGuiKey_A, 0, id); // 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 nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0; const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true); const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false)); - const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat)); + const bool is_cancel = Shortcut(ImGuiKey_Escape, f_repeat, id) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, f_repeat, id)); // FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of. + // FIXME-OSX: Missing support for Alt(option)+Right/Left = go to end of line, or next line if already in end of line. if (IsKeyPressed(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 (IsKeyPressed(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 (IsKeyPressed(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); } @@ -4519,7 +4578,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { if (is_wordmove_key_down) state->OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT); - else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) + else if (is_osx && io.KeyCtrl && !io.KeyAlt && !io.KeySuper) state->OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT); } state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); @@ -4539,7 +4598,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ else if (!is_readonly) { unsigned int c = '\n'; // Insert new line - if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Keyboard)) + if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data)) state->OnKeyPressed((int)c); } } @@ -4606,7 +4665,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ { unsigned int c; s += ImTextCharFromUtf8(&c, s, NULL); - if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, ImGuiInputSource_Clipboard)) + if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true)) continue; clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; } @@ -4689,7 +4748,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. ImGuiInputTextFlags event_flag = 0; ImGuiKey event_key = ImGuiKey_None; - if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && Shortcut(ImGuiKey_Tab, id)) + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && Shortcut(ImGuiKey_Tab, 0, id)) { event_flag = ImGuiInputTextFlags_CallbackCompletion; event_key = ImGuiKey_Tab; @@ -6194,13 +6253,17 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l label_end = FindRenderedTextEnd(label); const ImVec2 label_size = CalcTextSize(label, label_end, false); + const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing + const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it + const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow + // We vertically grow up to current line height up the typical widget height. const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL); ImRect frame_bb; frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; frame_bb.Min.y = window->DC.CursorPos.y; - frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x; + frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanTextWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x; frame_bb.Max.y = window->DC.CursorPos.y + frame_height; if (display_frame) { @@ -6210,16 +6273,13 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l frame_bb.Max.x += IM_TRUNC(window->WindowPadding.x * 0.5f); } - const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing - const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it - const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapsing ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); ItemSize(ImVec2(text_width, frame_height), padding.y); // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing ImRect interact_bb = frame_bb; - if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) - interact_bb.Max.x = frame_bb.Min.x + text_width + style.ItemSpacing.x * 2.0f; + if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanTextWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) + interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f); // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. const float backup_clip_rect_min_x = window->ClipRect.Min.x; @@ -6471,7 +6531,7 @@ void ImGui::SetNextItemOpen(bool is_open, ImGuiCond cond) return; g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasOpen; g.NextItemData.OpenVal = is_open; - g.NextItemData.OpenCond = cond ? cond : ImGuiCond_Always; + g.NextItemData.OpenCond = (ImU8)(cond ? cond : ImGuiCond_Always); } // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag). @@ -6755,7 +6815,7 @@ ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags f g.IO.InputQueueCharacters.resize(0); // Handle backspace - if ((flags & ImGuiTypingSelectFlags_AllowBackspace) && IsKeyPressed(ImGuiKey_Backspace, 0, ImGuiInputFlags_Repeat)) + if ((flags & ImGuiTypingSelectFlags_AllowBackspace) && IsKeyPressed(ImGuiKey_Backspace, ImGuiInputFlags_Repeat)) { char* p = (char*)(void*)ImTextFindPreviousUtf8Codepoint(data->SearchBuffer, data->SearchBuffer + buffer_len); *p = 0; @@ -6943,6 +7003,7 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) ImVec2 label_pos = ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y); RenderText(label_pos, label); window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, label_pos + label_size); + AlignTextToFramePadding(); } BeginChild(id, frame_bb.GetSize(), ImGuiChildFlags_FrameStyle); @@ -6986,6 +7047,7 @@ bool ImGui::ListBox(const char* label, int* current_item, const char* (*getter)( bool value_changed = false; ImGuiListClipper clipper; clipper.Begin(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. + clipper.IncludeItemByIndex(*current_item); while (clipper.Step()) for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { @@ -7504,7 +7566,7 @@ bool ImGui::BeginMenuEx(const char* label, const char* icon, bool enabled) // Menu inside an horizontal menu bar // Selectable extend their highlight by half ItemSpacing in each direction. // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() - popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight()); + popup_pos = ImVec2(pos.x - 1.0f - IM_TRUNC(style.ItemSpacing.x * 0.5f), pos.y - style.FramePadding.y + window->MenuBarHeight); window->DC.CursorPos.x += IM_TRUNC(style.ItemSpacing.x * 0.5f); PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); float w = label_size.x; @@ -8270,7 +8332,7 @@ ImGuiTabItem* ImGui::TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order) ImGuiTabItem* ImGui::TabBarGetCurrentTab(ImGuiTabBar* tab_bar) { - if (tab_bar->LastTabItemIdx <= 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size) + if (tab_bar->LastTabItemIdx < 0 || tab_bar->LastTabItemIdx >= tab_bar->Tabs.Size) return NULL; return &tab_bar->Tabs[tab_bar->LastTabItemIdx]; } diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.EXT.h b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.EXT.h index caab279..07f3c30 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.EXT.h +++ b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.EXT.h @@ -41,5 +41,6 @@ static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64"; static const char* const E_SPV_EXT_shader_tile_image = "SPV_EXT_shader_tile_image"; static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader"; +static const char* const E_SPV_ARM_cooperative_matrix_layouts = "SPV_ARM_cooperative_matrix_layouts"; #endif // #ifndef GLSLextEXT_H diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.KHR.h b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.KHR.h index 1d3af14..38d3b97 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.KHR.h +++ b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.KHR.h @@ -61,5 +61,7 @@ static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_coope static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence"; static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate"; static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume"; +static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_replicated_composites"; +static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relaxed_extended_instruction"; #endif // #ifndef GLSLextKHR_H diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.QCOM.h b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.QCOM.h index f13bb69..b52990f 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.QCOM.h +++ b/libs/bgfx/3rdparty/glslang/SPIRV/GLSL.ext.QCOM.h @@ -37,5 +37,7 @@ static const int GLSLextQCOMRevision = 1; //SPV_QCOM_image_processing const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing"; +//SPV_QCOM_image_processing2 +const char* const E_SPV_QCOM_image_processing2 = "SPV_QCOM_image_processing2"; #endif // #ifndef GLSLextQCOM_H diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp b/libs/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp index 187ecc0..0fd79b1 100755 --- a/libs/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/GlslangToSpv.cpp @@ -227,7 +227,9 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); + bool hasQCOMImageProceessingDecoration(spv::Id id, spv::Decoration decor); void addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor); + void addImageProcessing2QCOMDecoration(spv::Id id, bool isForGather); spv::Id createSpvConstant(const glslang::TIntermTyped&); spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); @@ -282,6 +284,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id taskPayloadID; // Used later for generating OpTraceKHR/OpExecuteCallableKHR/OpHitObjectRecordHit*/OpHitObjectGetShaderBindingTableData std::unordered_map locationToSymbol[4]; + std::unordered_map > idToQCOMDecorations; }; // @@ -397,11 +400,11 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector bool useVulkanMemoryModel) { if (!useVulkanMemoryModel) { - if (qualifier.isCoherent()) - memory.push_back(spv::DecorationCoherent); if (qualifier.isVolatile()) { memory.push_back(spv::DecorationVolatile); memory.push_back(spv::DecorationCoherent); + } else if (qualifier.isCoherent()) { + memory.push_back(spv::DecorationCoherent); } } if (qualifier.isRestrict()) @@ -986,18 +989,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInHitTriangleVertexPositionsKHR; case glslang::EbvInstanceCustomIndex: return spv::BuiltInInstanceCustomIndexKHR; - case glslang::EbvHitT: - { - // this is a GLSL alias of RayTmax - // in SPV_NV_ray_tracing it has a dedicated builtin - // but in SPV_KHR_ray_tracing it gets mapped to RayTmax - auto& extensions = glslangIntermediate->getRequestedExtensions(); - if (extensions.find("GL_NV_ray_tracing") != extensions.end()) { - return spv::BuiltInHitTNV; - } else { - return spv::BuiltInRayTmaxKHR; - } - } case glslang::EbvHitKind: return spv::BuiltInHitKindKHR; case glslang::EbvObjectToWorld: @@ -1592,6 +1583,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addInclude(iItr->first, iItr->second); } + builder.setUseReplicatedComposites(glslangIntermediate->usingReplicatedComposites()); + stdBuiltins = builder.import("GLSL.std.450"); spv::AddressingModel addressingModel = spv::AddressingModelLogical; @@ -2006,8 +1999,9 @@ void TGlslangToSpvTraverser::finishSpv(bool compileOnly) } // finish off the entry-point SPV instruction by adding the Input/Output - for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it) - entryPoint->addIdOperand(*it); + entryPoint->reserveOperands(iOSet.size()); + for (auto id : iOSet) + entryPoint->addIdOperand(id); } // Add capabilities, extensions, remove unneeded decorations, etc., @@ -3370,6 +3364,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.addExtension(spv::E_SPV_QCOM_image_processing); break; + case glslang::EOpImageBlockMatchWindowSSDQCOM: + case glslang::EOpImageBlockMatchWindowSADQCOM: + builder.addCapability(spv::CapabilityTextureBlockMatchQCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing); + builder.addCapability(spv::CapabilityTextureBlockMatch2QCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing2); + break; + + case glslang::EOpImageBlockMatchGatherSSDQCOM: + case glslang::EOpImageBlockMatchGatherSADQCOM: + builder.addCapability(spv::CapabilityTextureBlockMatchQCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing); + builder.addCapability(spv::CapabilityTextureBlockMatch2QCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing2); + break; + case glslang::EOpFetchMicroTriangleVertexPositionNV: case glslang::EOpFetchMicroTriangleVertexBarycentricNV: builder.addExtension(spv::E_SPV_NV_displacement_micromap); @@ -3695,6 +3705,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { idImmOps.push_back(spv::IdImmediate(true, operands[3])); // matrixLayout + auto layout = builder.getConstantScalar(operands[3]); + if (layout == spv::CooperativeMatrixLayoutRowBlockedInterleavedARM || + layout == spv::CooperativeMatrixLayoutColumnBlockedInterleavedARM) { + builder.addExtension(spv::E_SPV_ARM_cooperative_matrix_layouts); + builder.addCapability(spv::CapabilityCooperativeMatrixLayoutsARM); + } idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride } else { idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride @@ -3719,6 +3735,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt idImmOps.push_back(spv::IdImmediate(true, operands[0])); // object if (node->getOp() == glslang::EOpCooperativeMatrixStore) { idImmOps.push_back(spv::IdImmediate(true, operands[3])); // matrixLayout + auto layout = builder.getConstantScalar(operands[3]); + if (layout == spv::CooperativeMatrixLayoutRowBlockedInterleavedARM || + layout == spv::CooperativeMatrixLayoutColumnBlockedInterleavedARM) { + builder.addExtension(spv::E_SPV_ARM_cooperative_matrix_layouts); + builder.addCapability(spv::CapabilityCooperativeMatrixLayoutsARM); + } idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride } else { idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride @@ -5361,17 +5383,34 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout, matrixLayout == glslang::ElmRowMajor); + bool isVectorLike = memberType.isVector(); + if (memberType.isMatrix()) { + if (matrixLayout == glslang::ElmRowMajor) + isVectorLike = memberType.getMatrixRows() == 1; + else + isVectorLike = memberType.getMatrixCols() == 1; + } + // Adjust alignment for HLSL rules // TODO: make this consistent in early phases of code: // adjusting this late means inconsistencies with earlier code, which for reflection is an issue // Until reflection is brought in sync with these adjustments, don't apply to $Global, // which is the most likely to rely on reflection, and least likely to rely implicit layouts if (glslangIntermediate->usingHlslOffsets() && - ! memberType.isArray() && memberType.isVector() && structType.getTypeName().compare("$Global") != 0) { - int dummySize; - int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize); - if (componentAlignment <= 4) + ! memberType.isStruct() && structType.getTypeName().compare("$Global") != 0) { + int componentSize; + int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, componentSize); + if (! memberType.isArray() && isVectorLike && componentAlignment <= 4) memberAlignment = componentAlignment; + + // Don't add unnecessary padding after this member + if (memberType.isMatrix()) { + if (matrixLayout == glslang::ElmRowMajor) + memberSize -= componentSize * (4 - memberType.getMatrixCols()); + else + memberSize -= componentSize * (4 - memberType.getMatrixRows()); + } else if (memberType.isArray()) + memberSize -= componentSize * (4 - memberType.getVectorSize()); } // Bump up to member alignment @@ -5379,7 +5418,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType // Bump up to vec4 if there is a bad straddle if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize, - currentOffset)) + currentOffset, isVectorLike)) glslang::RoundToPow2(currentOffset, 16); nextOffset = currentOffset + memberSize; @@ -5464,8 +5503,10 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF // memory and use RestrictPointer/AliasedPointer. if (originalParam(type.getQualifier().storage, type, false) || !writableParam(type.getQualifier().storage)) { - decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict : - spv::DecorationAliased); + // TranslateMemoryDecoration added Restrict decoration already. + if (!type.getQualifier().isRestrict()) { + decorations.push_back(spv::DecorationAliased); + } } else { decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); @@ -5760,8 +5801,16 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& lvalueCoherentFlags = builder.getAccessChain().coherentFlags; builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags)); lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType()); - } else - arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); + } else { + if (i > 0 && + glslangArguments[i]->getAsSymbolNode() && glslangArguments[i-1]->getAsSymbolNode() && + glslangArguments[i]->getAsSymbolNode()->getId() == glslangArguments[i-1]->getAsSymbolNode()->getId()) { + // Reuse the id if possible + arguments.push_back(arguments[i-1]); + } else { + arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); + } + } } } @@ -8040,6 +8089,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv } std::vector spvAtomicOperands; // hold the spv operands + spvAtomicOperands.reserve(6); spvAtomicOperands.push_back(pointerId); spvAtomicOperands.push_back(scopeId); spvAtomicOperands.push_back(semanticsId); @@ -9268,6 +9318,30 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: opCode = spv::OpFetchMicroTriangleVertexPositionNV; break; + case glslang::EOpImageBlockMatchWindowSSDQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchWindowSSDQCOM; + addImageProcessing2QCOMDecoration(operands[0], false); + addImageProcessing2QCOMDecoration(operands[2], false); + break; + case glslang::EOpImageBlockMatchWindowSADQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchWindowSADQCOM; + addImageProcessing2QCOMDecoration(operands[0], false); + addImageProcessing2QCOMDecoration(operands[2], false); + break; + case glslang::EOpImageBlockMatchGatherSSDQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchGatherSSDQCOM; + addImageProcessing2QCOMDecoration(operands[0], true); + addImageProcessing2QCOMDecoration(operands[2], true); + break; + case glslang::EOpImageBlockMatchGatherSADQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchGatherSADQCOM; + addImageProcessing2QCOMDecoration(operands[0], true); + addImageProcessing2QCOMDecoration(operands[2], true); + break; default: return 0; } @@ -9774,6 +9848,16 @@ void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const g } } +bool TGlslangToSpvTraverser::hasQCOMImageProceessingDecoration(spv::Id id, spv::Decoration decor) +{ + std::vector &decoVec = idToQCOMDecorations[id]; + for ( auto d : decoVec ) { + if ( d == decor ) + return true; + } + return false; +} + void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor) { spv::Op opc = builder.getOpCode(id); @@ -9784,7 +9868,43 @@ void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::D if (opc == spv::OpLoad) { spv::Id texid = builder.getIdOperand(id, 0); - builder.addDecoration(texid, decor); + if (!hasQCOMImageProceessingDecoration(texid, decor)) {// + builder.addDecoration(texid, decor); + idToQCOMDecorations[texid].push_back(decor); + } + } +} + +void TGlslangToSpvTraverser::addImageProcessing2QCOMDecoration(spv::Id id, bool isForGather) +{ + if (isForGather) { + return addImageProcessingQCOMDecoration(id, spv::DecorationBlockMatchTextureQCOM); + } + + auto addDecor = + [this](spv::Id id, spv::Decoration decor) { + spv::Id tsopc = this->builder.getOpCode(id); + if (tsopc == spv::OpLoad) { + spv::Id tsid = this->builder.getIdOperand(id, 0); + if (this->glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) { + assert(iOSet.count(tsid) > 0); + } + if (!hasQCOMImageProceessingDecoration(tsid, decor)) { + this->builder.addDecoration(tsid, decor); + idToQCOMDecorations[tsid].push_back(decor); + } + } + }; + + spv::Id opc = builder.getOpCode(id); + bool isInterfaceObject = (opc != spv::OpSampledImage); + + if (!isInterfaceObject) { + addDecor(builder.getIdOperand(id, 0), spv::DecorationBlockMatchTextureQCOM); + addDecor(builder.getIdOperand(id, 1), spv::DecorationBlockMatchSamplerQCOM); + } else { + addDecor(id, spv::DecorationBlockMatchTextureQCOM); + addDecor(id, spv::DecorationBlockMatchSamplerQCOM); } } @@ -10114,6 +10234,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan // Operands to accumulate OpPhi operands std::vector phiOperands; + phiOperands.reserve(4); // accumulate left operand's phi information phiOperands.push_back(leftId); phiOperands.push_back(builder.getBuildPoint()->getId()); @@ -10153,7 +10274,6 @@ spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) if (extBuiltinMap.find(name) != extBuiltinMap.end()) return extBuiltinMap[name]; else { - builder.addExtension(name); spv::Id extBuiltins = builder.import(name); extBuiltinMap[name] = extBuiltins; return extBuiltins; diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp b/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp index 062a7c7..51c6bc2 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.cpp @@ -157,6 +157,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee) // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypePointer); + type->reserveOperands(2); type->addImmediateOperand(storageClass); type->addIdOperand(pointee); groupedTypes[OpTypePointer].push_back(type); @@ -181,6 +182,10 @@ Id Builder::makeForwardPointer(StorageClass storageClass) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) { + const Id debugResultId = makeForwardPointerDebugType(storageClass); + debugId[type->getResultId()] = debugResultId; + } return type->getResultId(); } @@ -196,12 +201,22 @@ Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardP } type = new Instruction(forwardPointerType, NoType, OpTypePointer); + type->reserveOperands(2); type->addImmediateOperand(storageClass); type->addIdOperand(pointee); groupedTypes[OpTypePointer].push_back(type); constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + // If we are emitting nonsemantic debuginfo, we need to patch the debug pointer type + // that was emitted alongside the forward pointer, now that we have a pointee debug + // type for it to point to. + if (emitNonSemanticShaderDebugInfo) { + Instruction *debugForwardPointer = module.getInstruction(debugId[forwardPointerType]); + assert(debugId[pointee]); + debugForwardPointer->setIdOperand(2, debugId[pointee]); + } + return type->getResultId(); } @@ -218,6 +233,7 @@ Id Builder::makeIntegerType(int width, bool hasSign) // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeInt); + type->reserveOperands(2); type->addImmediateOperand(width); type->addImmediateOperand(hasSign ? 1 : 0); groupedTypes[OpTypeInt].push_back(type); @@ -348,6 +364,7 @@ Id Builder::makeVectorType(Id component, int size) // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeVector); + type->reserveOperands(2); type->addIdOperand(component); type->addImmediateOperand(size); groupedTypes[OpTypeVector].push_back(type); @@ -380,6 +397,7 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeMatrix); + type->reserveOperands(2); type->addIdOperand(column); type->addImmediateOperand(cols); groupedTypes[OpTypeMatrix].push_back(type); @@ -411,6 +429,7 @@ Id Builder::makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id col // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixKHR); + type->reserveOperands(5); type->addIdOperand(component); type->addIdOperand(scope); type->addIdOperand(rows); @@ -436,6 +455,7 @@ Id Builder::makeCooperativeMatrixTypeNV(Id component, Id scope, Id rows, Id cols // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixNV); + type->reserveOperands(4); type->addIdOperand(component); type->addIdOperand(scope); type->addIdOperand(rows); @@ -477,6 +497,7 @@ Id Builder::makeGenericType(spv::Op opcode, std::vector& opera // not found, make it type = new Instruction(getUniqueId(), NoType, opcode); + type->reserveOperands(operands.size()); for (size_t op = 0; op < operands.size(); ++op) { if (operands[op].isId) type->addIdOperand(operands[op].word); @@ -509,6 +530,7 @@ Id Builder::makeArrayType(Id element, Id sizeId, int stride) // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeArray); + type->reserveOperands(2); type->addIdOperand(element); type->addIdOperand(sizeId); groupedTypes[OpTypeArray].push_back(type); @@ -575,6 +597,7 @@ Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) // not found, make it Id typeId = getUniqueId(); type = new Instruction(typeId, NoType, OpTypeFunction); + type->reserveOperands(paramTypes.size() + 1); type->addIdOperand(returnType); for (int p = 0; p < (int)paramTypes.size(); ++p) type->addIdOperand(paramTypes[p]); @@ -597,6 +620,7 @@ Id Builder::makeDebugFunctionType(Id returnType, const std::vector& paramTyp Id typeId = getUniqueId(); auto type = new Instruction(typeId, makeVoidType(), OpExtInst); + type->reserveOperands(paramTypes.size() + 4); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeFunction); type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); @@ -635,6 +659,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo // not found, make it type = new Instruction(getUniqueId(), NoType, OpTypeImage); + type->reserveOperands(7); type->addIdOperand(sampledType); type->addImmediateOperand( dim); type->addImmediateOperand( depth ? 1 : 0); @@ -745,6 +770,7 @@ Id Builder::makeDebugInfoNone() return debugInfoNone; Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(2); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugInfoNone); @@ -769,6 +795,7 @@ Id Builder::makeBoolDebugType(int const size) } type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(6); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); @@ -806,6 +833,7 @@ Id Builder::makeIntegerDebugType(int const width, bool const hasSign) // not found, make it type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(6); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); type->addIdOperand(nameId); // name id @@ -845,6 +873,7 @@ Id Builder::makeFloatDebugType(int const width) // not found, make it type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(6); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); type->addIdOperand(nameId); // name id @@ -875,6 +904,7 @@ Id Builder::makeSequentialDebugType(Id const baseType, Id const componentCount, // not found, make it type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(4); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(sequenceType); type->addIdOperand(debugId[baseType]); // base type @@ -910,6 +940,7 @@ Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool // not found, make it type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(5); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMatrix); type->addIdOperand(debugId[vectorType]); // vector type id @@ -928,6 +959,7 @@ Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTy assert(debugId[memberType] != 0); Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(10); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember); type->addIdOperand(getStringId(debugTypeLoc.name)); // name id @@ -967,6 +999,7 @@ Id Builder::makeCompositeDebugType(std::vector const& memberTypes, char cons // Create The structure debug type. Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(memberDebugTypes.size() + 11); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeComposite); type->addIdOperand(getStringId(name)); // name id @@ -1011,6 +1044,7 @@ Id Builder::makePointerDebugType(StorageClass storageClass, Id const baseType) } Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->reserveOperands(5); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypePointer); type->addIdOperand(debugBaseType); @@ -1024,11 +1058,35 @@ Id Builder::makePointerDebugType(StorageClass storageClass, Id const baseType) return type->getResultId(); } +// Emit a OpExtInstWithForwardRefsKHR nonsemantic instruction for a pointer debug type +// where we don't have the pointee yet. Since we don't have the pointee yet, it just +// points to itself and we rely on patching it later. +Id Builder::makeForwardPointerDebugType(StorageClass storageClass) +{ + const Id scID = makeUintConstant(storageClass); + + this->addExtension(spv::E_SPV_KHR_relaxed_extended_instruction); + + Instruction *type = new Instruction(getUniqueId(), makeVoidType(), OpExtInstWithForwardRefsKHR); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypePointer); + type->addIdOperand(type->getResultId()); + type->addIdOperand(scID); + type->addIdOperand(makeUintConstant(0)); + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypePointer].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + Id Builder::makeDebugSource(const Id fileName) { if (debugSourceId.find(fileName) != debugSourceId.end()) return debugSourceId[fileName]; spv::Id resultId = getUniqueId(); Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst); + sourceInst->reserveOperands(3); sourceInst->addIdOperand(nonSemanticShaderDebugInfo); sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugSource); sourceInst->addIdOperand(fileName); @@ -1059,6 +1117,7 @@ Id Builder::makeDebugCompilationUnit() { return nonSemanticShaderCompilationUnitId; spv::Id resultId = getUniqueId(); Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst); + sourceInst->reserveOperands(6); sourceInst->addIdOperand(nonSemanticShaderDebugInfo); sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugCompilationUnit); sourceInst->addIdOperand(makeUintConstant(1)); // TODO(greg-lunarg): Get rid of magic number @@ -1082,6 +1141,7 @@ Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id c assert(type != 0); Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(11); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugGlobalVariable); inst->addIdOperand(getStringId(name)); // name id @@ -1106,6 +1166,7 @@ Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t cons assert(!currentDebugScopeId.empty()); Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(9); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable); inst->addIdOperand(getStringId(name)); // name id @@ -1131,6 +1192,7 @@ Id Builder::makeDebugExpression() return debugExpression; Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(2); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugExpression); @@ -1145,6 +1207,7 @@ Id Builder::makeDebugExpression() Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer) { Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(5); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare); inst->addIdOperand(debugLocalVariable); // debug local variable id @@ -1158,6 +1221,7 @@ Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer) Id Builder::makeDebugValue(Id const debugLocalVariable, Id const value) { Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->reserveOperands(5); inst->addIdOperand(nonSemanticShaderDebugInfo); inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugValue); inst->addIdOperand(debugLocalVariable); // debug local variable id @@ -1456,12 +1520,14 @@ bool Builder::isConstantOpCode(Op opcode) const case OpConstantFalse: case OpConstant: case OpConstantComposite: + case OpConstantCompositeReplicateEXT: case OpConstantSampler: case OpConstantNull: case OpSpecConstantTrue: case OpSpecConstantFalse: case OpSpecConstant: case OpSpecConstantComposite: + case OpSpecConstantCompositeReplicateEXT: case OpSpecConstantOp: return true; default: @@ -1478,6 +1544,7 @@ bool Builder::isSpecConstantOpCode(Op opcode) const case OpSpecConstant: case OpSpecConstantComposite: case OpSpecConstantOp: + case OpSpecConstantCompositeReplicateEXT: return true; default: return false; @@ -1574,6 +1641,7 @@ Id Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specCons } Instruction* c = new Instruction(getUniqueId(), typeId, opcode); + c->reserveOperands(2); c->addImmediateOperand(op1); c->addImmediateOperand(op2); constantsTypesGlobals.push_back(std::unique_ptr(c)); @@ -1627,6 +1695,7 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) } Instruction* c = new Instruction(getUniqueId(), typeId, opcode); + c->reserveOperands(2); c->addImmediateOperand(op1); c->addImmediateOperand(op2); constantsTypesGlobals.push_back(std::unique_ptr(c)); @@ -1752,10 +1821,27 @@ Id Builder::findStructConstant(Id typeId, const std::vector& comps) // Comments in header Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, bool specConstant) { - Op opcode = specConstant ? OpSpecConstantComposite : OpConstantComposite; assert(typeId); Op typeClass = getTypeClass(typeId); + bool replicate = false; + size_t numMembers = members.size(); + if (useReplicatedComposites) { + // use replicate if all members are the same + replicate = numMembers > 0 && + std::equal(members.begin() + 1, members.end(), members.begin()); + + if (replicate) { + numMembers = 1; + addCapability(spv::CapabilityReplicatedCompositesEXT); + addExtension(spv::E_SPV_EXT_replicated_composites); + } + } + + Op opcode = replicate ? + (specConstant ? OpSpecConstantCompositeReplicateEXT : OpConstantCompositeReplicateEXT) : + (specConstant ? OpSpecConstantComposite : OpConstantComposite); + switch (typeClass) { case OpTypeVector: case OpTypeArray: @@ -1781,7 +1867,8 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, boo } Instruction* c = new Instruction(getUniqueId(), typeId, opcode); - for (int op = 0; op < (int)members.size(); ++op) + c->reserveOperands(members.size()); + for (size_t op = 0; op < numMembers; ++op) c->addIdOperand(members[op]); constantsTypesGlobals.push_back(std::unique_ptr(c)); if (typeClass == OpTypeStruct) @@ -1796,6 +1883,7 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, boo Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, const char* name) { Instruction* entryPoint = new Instruction(OpEntryPoint); + entryPoint->reserveOperands(3); entryPoint->addImmediateOperand(model); entryPoint->addIdOperand(function->getId()); entryPoint->addStringOperand(name); @@ -1813,6 +1901,7 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val return; Instruction* instr = new Instruction(OpExecutionMode); + instr->reserveOperands(3); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); if (value1 >= 0) @@ -1832,6 +1921,7 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const s return; Instruction* instr = new Instruction(OpExecutionMode); + instr->reserveOperands(literals.size() + 2); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); for (auto literal : literals) @@ -1847,6 +1937,7 @@ void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const return; Instruction* instr = new Instruction(OpExecutionModeId); + instr->reserveOperands(operandIds.size() + 2); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); for (auto operandId : operandIds) @@ -1858,6 +1949,7 @@ void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const void Builder::addName(Id id, const char* string) { Instruction* name = new Instruction(OpName); + name->reserveOperands(2); name->addIdOperand(id); name->addStringOperand(string); @@ -1867,6 +1959,7 @@ void Builder::addName(Id id, const char* string) void Builder::addMemberName(Id id, int memberNumber, const char* string) { Instruction* name = new Instruction(OpMemberName); + name->reserveOperands(3); name->addIdOperand(id); name->addImmediateOperand(memberNumber); name->addStringOperand(string); @@ -1880,6 +1973,7 @@ void Builder::addDecoration(Id id, Decoration decoration, int num) return; Instruction* dec = new Instruction(OpDecorate); + dec->reserveOperands(2); dec->addIdOperand(id); dec->addImmediateOperand(decoration); if (num >= 0) @@ -1894,6 +1988,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const char* s) return; Instruction* dec = new Instruction(OpDecorateString); + dec->reserveOperands(3); dec->addIdOperand(id); dec->addImmediateOperand(decoration); dec->addStringOperand(s); @@ -1907,6 +2002,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vectorreserveOperands(literals.size() + 2); dec->addIdOperand(id); dec->addImmediateOperand(decoration); for (auto literal : literals) @@ -1921,6 +2017,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vectorreserveOperands(strings.size() + 2); dec->addIdOperand(id); dec->addImmediateOperand(decoration); for (auto string : strings) @@ -1931,6 +2028,7 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vectorreserveOperands(4); dec->addIdOperand(id); dec->addImmediateOperand(spv::DecorationLinkageAttributes); dec->addStringOperand(name); @@ -1945,6 +2043,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) return; Instruction* dec = new Instruction(OpDecorateId); + dec->reserveOperands(3); dec->addIdOperand(id); dec->addImmediateOperand(decoration); dec->addIdOperand(idDecoration); @@ -1958,6 +2057,7 @@ void Builder::addDecorationId(Id id, Decoration decoration, const std::vectorreserveOperands(operandIds.size() + 2); dec->addIdOperand(id); dec->addImmediateOperand(decoration); @@ -1973,6 +2073,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat return; Instruction* dec = new Instruction(OpMemberDecorate); + dec->reserveOperands(3); dec->addIdOperand(id); dec->addImmediateOperand(member); dec->addImmediateOperand(decoration); @@ -1988,6 +2089,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat return; Instruction* dec = new Instruction(OpMemberDecorateStringGOOGLE); + dec->reserveOperands(4); dec->addIdOperand(id); dec->addImmediateOperand(member); dec->addImmediateOperand(decoration); @@ -2002,6 +2104,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat return; Instruction* dec = new Instruction(OpMemberDecorate); + dec->reserveOperands(literals.size() + 3); dec->addIdOperand(id); dec->addImmediateOperand(member); dec->addImmediateOperand(decoration); @@ -2017,6 +2120,7 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat return; Instruction* dec = new Instruction(OpMemberDecorateString); + dec->reserveOperands(strings.size() + 3); dec->addIdOperand(id); dec->addImmediateOperand(member); dec->addImmediateOperand(decoration); @@ -2031,6 +2135,7 @@ void Builder::addInstruction(std::unique_ptr inst) { if (emitNonSemanticShaderDebugInfo && dirtyScopeTracker) { if (buildPoint->updateDebugScope(currentDebugScopeId.top())) { auto scopeInst = std::make_unique(getUniqueId(), makeVoidType(), OpExtInst); + scopeInst->reserveOperands(3); scopeInst->addIdOperand(nonSemanticShaderDebugInfo); scopeInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugScope); scopeInst->addIdOperand(currentDebugScopeId.top()); @@ -2045,6 +2150,7 @@ void Builder::addInstruction(std::unique_ptr inst) { if (buildPoint->updateDebugSourceLocation(currentLine, 0, currentFileId)) { if (emitSpirvDebugInfo) { auto lineInst = std::make_unique(OpLine); + lineInst->reserveOperands(3); lineInst->addIdOperand(currentFileId); lineInst->addImmediateOperand(currentLine); lineInst->addImmediateOperand(0); @@ -2052,6 +2158,7 @@ void Builder::addInstruction(std::unique_ptr inst) { } if (emitNonSemanticShaderDebugInfo) { auto lineInst = std::make_unique(getUniqueId(), makeVoidType(), OpExtInst); + lineInst->reserveOperands(7); lineInst->addIdOperand(nonSemanticShaderDebugInfo); lineInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLine); lineInst->addIdOperand(makeDebugSource(currentFileId)); @@ -2191,6 +2298,7 @@ Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id Id funcId = getUniqueId(); auto type = new Instruction(funcId, makeVoidType(), OpExtInst); + type->reserveOperands(11); type->addIdOperand(nonSemanticShaderDebugInfo); type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunction); type->addIdOperand(nameId); @@ -2212,6 +2320,7 @@ Id Builder::makeDebugLexicalBlock(uint32_t line) { Id lexId = getUniqueId(); auto lex = new Instruction(lexId, makeVoidType(), OpExtInst); + lex->reserveOperands(6); lex->addIdOperand(nonSemanticShaderDebugInfo); lex->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLexicalBlock); lex->addIdOperand(makeDebugSource(currentFileId)); @@ -2282,6 +2391,7 @@ void Builder::enterFunction(Function const* function) // Create DebugFunctionDefinition spv::Id resultId = getUniqueId(); Instruction* defInst = new Instruction(resultId, makeVoidType(), OpExtInst); + defInst->reserveOperands(4); defInst->addIdOperand(nonSemanticShaderDebugInfo); defInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunctionDefinition); defInst->addIdOperand(debugId[funcId]); @@ -2413,6 +2523,7 @@ void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAcce unsigned int alignment) { Instruction* store = new Instruction(OpStore); + store->reserveOperands(2); store->addIdOperand(lValue); store->addIdOperand(rValue); @@ -2465,6 +2576,7 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, const std::vec // Make the instruction Instruction* chain = new Instruction(getUniqueId(), typeId, OpAccessChain); + chain->reserveOperands(offsets.size() + 1); chain->addIdOperand(base); for (int i = 0; i < (int)offsets.size(); ++i) chain->addIdOperand(offsets[i]); @@ -2477,6 +2589,7 @@ Id Builder::createArrayLength(Id base, unsigned int member) { spv::Id intType = makeUintType(32); Instruction* length = new Instruction(getUniqueId(), intType, OpArrayLength); + length->reserveOperands(2); length->addIdOperand(base); length->addImmediateOperand(member); addInstruction(std::unique_ptr(length)); @@ -2527,6 +2640,7 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index) std::vector(1, index)); } Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract); + extract->reserveOperands(2); extract->addIdOperand(composite); extract->addImmediateOperand(index); addInstruction(std::unique_ptr(extract)); @@ -2542,6 +2656,7 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, const std::vector(1, composite), indexes); } Instruction* extract = new Instruction(getUniqueId(), typeId, OpCompositeExtract); + extract->reserveOperands(indexes.size() + 1); extract->addIdOperand(composite); for (int i = 0; i < (int)indexes.size(); ++i) extract->addImmediateOperand(indexes[i]); @@ -2553,6 +2668,7 @@ Id Builder::createCompositeExtract(Id composite, Id typeId, const std::vectorreserveOperands(3); insert->addIdOperand(object); insert->addIdOperand(composite); insert->addImmediateOperand(index); @@ -2564,6 +2680,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, unsigned i Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, const std::vector& indexes) { Instruction* insert = new Instruction(getUniqueId(), typeId, OpCompositeInsert); + insert->reserveOperands(indexes.size() + 2); insert->addIdOperand(object); insert->addIdOperand(composite); for (int i = 0; i < (int)indexes.size(); ++i) @@ -2576,6 +2693,7 @@ Id Builder::createCompositeInsert(Id object, Id composite, Id typeId, const std: Id Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex) { Instruction* extract = new Instruction(getUniqueId(), typeId, OpVectorExtractDynamic); + extract->reserveOperands(2); extract->addIdOperand(vector); extract->addIdOperand(componentIndex); addInstruction(std::unique_ptr(extract)); @@ -2586,6 +2704,7 @@ Id Builder::createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex) Id Builder::createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex) { Instruction* insert = new Instruction(getUniqueId(), typeId, OpVectorInsertDynamic); + insert->reserveOperands(3); insert->addIdOperand(vector); insert->addIdOperand(component); insert->addIdOperand(componentIndex); @@ -2613,8 +2732,9 @@ void Builder::createNoResultOp(Op opCode, Id operand) void Builder::createNoResultOp(Op opCode, const std::vector& operands) { Instruction* op = new Instruction(opCode); - for (auto it = operands.cbegin(); it != operands.cend(); ++it) { - op->addIdOperand(*it); + op->reserveOperands(operands.size()); + for (auto id : operands) { + op->addIdOperand(id); } addInstruction(std::unique_ptr(op)); } @@ -2623,6 +2743,7 @@ void Builder::createNoResultOp(Op opCode, const std::vector& operands) void Builder::createNoResultOp(Op opCode, const std::vector& operands) { Instruction* op = new Instruction(opCode); + op->reserveOperands(operands.size()); for (auto it = operands.cbegin(); it != operands.cend(); ++it) { if (it->isId) op->addIdOperand(it->word); @@ -2635,6 +2756,7 @@ void Builder::createNoResultOp(Op opCode, const std::vector& operan void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask semantics) { Instruction* op = new Instruction(OpControlBarrier); + op->reserveOperands(3); op->addIdOperand(makeUintConstant(execution)); op->addIdOperand(makeUintConstant(memory)); op->addIdOperand(makeUintConstant(semantics)); @@ -2644,6 +2766,7 @@ void Builder::createControlBarrier(Scope execution, Scope memory, MemorySemantic void Builder::createMemoryBarrier(unsigned executionScope, unsigned memorySemantics) { Instruction* op = new Instruction(OpMemoryBarrier); + op->reserveOperands(2); op->addIdOperand(makeUintConstant(executionScope)); op->addIdOperand(makeUintConstant(memorySemantics)); addInstruction(std::unique_ptr(op)); @@ -2674,6 +2797,7 @@ Id Builder::createBinOp(Op opCode, Id typeId, Id left, Id right) return createSpecConstantOp(opCode, typeId, operands, std::vector()); } Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + op->reserveOperands(2); op->addIdOperand(left); op->addIdOperand(right); addInstruction(std::unique_ptr(op)); @@ -2694,6 +2818,7 @@ Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3) opCode, typeId, operands, std::vector()); } Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + op->reserveOperands(3); op->addIdOperand(op1); op->addIdOperand(op2); op->addIdOperand(op3); @@ -2705,8 +2830,9 @@ Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3) Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) { Instruction* op = new Instruction(getUniqueId(), typeId, opCode); - for (auto it = operands.cbegin(); it != operands.cend(); ++it) - op->addIdOperand(*it); + op->reserveOperands(operands.size()); + for (auto id : operands) + op->addIdOperand(id); addInstruction(std::unique_ptr(op)); return op->getResultId(); @@ -2715,6 +2841,7 @@ Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) Id Builder::createOp(Op opCode, Id typeId, const std::vector& operands) { Instruction* op = new Instruction(getUniqueId(), typeId, opCode); + op->reserveOperands(operands.size()); for (auto it = operands.cbegin(); it != operands.cend(); ++it) { if (it->isId) op->addIdOperand(it->word); @@ -2730,6 +2857,7 @@ Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& op const std::vector& literals) { Instruction* op = new Instruction(getUniqueId(), typeId, OpSpecConstantOp); + op->reserveOperands(operands.size() + literals.size() + 1); op->addImmediateOperand((unsigned) opCode); for (auto it = operands.cbegin(); it != operands.cend(); ++it) op->addIdOperand(*it); @@ -2752,6 +2880,7 @@ Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& op Id Builder::createFunctionCall(spv::Function* function, const std::vector& args) { Instruction* op = new Instruction(getUniqueId(), function->getReturnType(), OpFunctionCall); + op->reserveOperands(args.size() + 1); op->addIdOperand(function->getId()); for (int a = 0; a < (int)args.size(); ++a) op->addIdOperand(args[a]); @@ -2773,6 +2902,7 @@ Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, cons } Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle); assert(isVector(source)); + swizzle->reserveOperands(channels.size() + 2); swizzle->addIdOperand(source); swizzle->addIdOperand(source); for (int i = 0; i < (int)channels.size(); ++i) @@ -2791,6 +2921,7 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle); assert(isVector(target)); + swizzle->reserveOperands(2); swizzle->addIdOperand(target); assert(getNumComponents(source) == (int)channels.size()); @@ -2808,6 +2939,7 @@ Id Builder::createLvalueSwizzle(Id typeId, Id target, Id source, const std::vect components[channels[i]] = numTargetComponents + i; // finish the instruction with these components selectors + swizzle->reserveOperands(numTargetComponents); for (int i = 0; i < numTargetComponents; ++i) swizzle->addImmediateOperand(components[i]); addInstruction(std::unique_ptr(swizzle)); @@ -2852,7 +2984,18 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType) auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar)); smear = module.getInstruction(result_id); } else { - smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct); + bool replicate = useReplicatedComposites && (numComponents > 0); + + if (replicate) { + numComponents = 1; + addCapability(spv::CapabilityReplicatedCompositesEXT); + addExtension(spv::E_SPV_EXT_replicated_composites); + } + + Op opcode = replicate ? OpCompositeConstructReplicateEXT : OpCompositeConstruct; + + smear = new Instruction(getUniqueId(), vectorType, opcode); + smear->reserveOperands(numComponents); for (int c = 0; c < numComponents; ++c) smear->addIdOperand(scalar); addInstruction(std::unique_ptr(smear)); @@ -2865,6 +3008,7 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType) Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector& args) { Instruction* inst = new Instruction(getUniqueId(), resultType, OpExtInst); + inst->reserveOperands(args.size() + 2); inst->addIdOperand(builtins); inst->addImmediateOperand(entryPoint); for (int arg = 0; arg < (int)args.size(); ++arg) @@ -3059,6 +3203,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // Build the SPIR-V instruction Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode); + textureInst->reserveOperands(optArgNum + (texArgs.size() - (optArgNum + 1))); for (size_t op = 0; op < optArgNum; ++op) textureInst->addIdOperand(texArgs[op]); if (optArgNum < texArgs.size()) @@ -3242,8 +3387,25 @@ Id Builder::createCompositeConstruct(Id typeId, const std::vector& constitue [&](spv::Id id) { return isSpecConstant(id); })); } - Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct); - for (int c = 0; c < (int)constituents.size(); ++c) + bool replicate = false; + size_t numConstituents = constituents.size(); + + if (useReplicatedComposites) { + replicate = numConstituents > 0 && + std::equal(constituents.begin() + 1, constituents.end(), constituents.begin()); + } + + if (replicate) { + numConstituents = 1; + addCapability(spv::CapabilityReplicatedCompositesEXT); + addExtension(spv::E_SPV_EXT_replicated_composites); + } + + Op opcode = replicate ? OpCompositeConstructReplicateEXT : OpCompositeConstruct; + + Instruction* op = new Instruction(getUniqueId(), typeId, opcode); + op->reserveOperands(constituents.size()); + for (size_t c = 0; c < numConstituents; ++c) op->addIdOperand(constituents[c]); addInstruction(std::unique_ptr(op)); @@ -3329,10 +3491,13 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc } // If the result is a vector, make it from the gathered constituents. - if (constituents.size() > 0) + if (constituents.size() > 0) { result = createCompositeConstruct(resultTypeId, constituents); - - return setPrecision(result, precision); + return setPrecision(result, precision); + } else { + // Precision was set when generating this component. + return result; + } } // Comments in header @@ -3375,6 +3540,13 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision); } + // Detect a matrix being constructed from a repeated vector of the correct size. + // Create the composite directly from it. + if ((int)sources.size() == numCols && isVector(sources[0]) && getNumComponents(sources[0]) == numRows && + std::equal(sources.begin() + 1, sources.end(), sources.begin())) { + return setPrecision(createCompositeConstruct(resultTypeId, sources), precision); + } + // Otherwise, will use a two step process // 1. make a compile-time 2D array of values // 2. construct a matrix from that array @@ -3532,6 +3704,7 @@ void Builder::makeSwitch(Id selector, unsigned int control, int numSegments, con // make the switch instruction Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch); + switchInst->reserveOperands((caseValues.size() * 2) + 2); switchInst->addIdOperand(selector); auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock; switchInst->addIdOperand(defaultOrMerge->getId()); @@ -4067,6 +4240,7 @@ void Builder::createBranch(Block* block) void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control) { Instruction* merge = new Instruction(OpSelectionMerge); + merge->reserveOperands(2); merge->addIdOperand(mergeBlock->getId()); merge->addImmediateOperand(control); addInstruction(std::unique_ptr(merge)); @@ -4076,6 +4250,7 @@ void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned const std::vector& operands) { Instruction* merge = new Instruction(OpLoopMerge); + merge->reserveOperands(operands.size() + 3); merge->addIdOperand(mergeBlock->getId()); merge->addIdOperand(continueBlock->getId()); merge->addImmediateOperand(control); @@ -4087,6 +4262,7 @@ void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock) { Instruction* branch = new Instruction(OpBranchConditional); + branch->reserveOperands(3); branch->addIdOperand(condition); branch->addIdOperand(thenBlock->getId()); branch->addIdOperand(elseBlock->getId()); @@ -4108,6 +4284,7 @@ void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& te if (sourceLang != SourceLanguageUnknown) { // OpSource Language Version File Source Instruction sourceInst(NoResult, NoType, OpSource); + sourceInst.reserveOperands(3); sourceInst.addImmediateOperand(sourceLang); sourceInst.addImmediateOperand(sourceVersion); // File operand diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.h b/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.h index a65a98e..35327d6 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.h +++ b/libs/bgfx/3rdparty/glslang/SPIRV/SpvBuilder.h @@ -235,6 +235,7 @@ class Builder { Id makeCompositeDebugType(std::vector const& memberTypes, char const*const name, NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType = false); Id makePointerDebugType(StorageClass storageClass, Id const baseType); + Id makeForwardPointerDebugType(StorageClass storageClass); Id makeDebugSource(const Id fileName); Id makeDebugCompilationUnit(); Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable); @@ -855,6 +856,8 @@ class Builder { void postProcess(Instruction&); // Hook to visit each non-32-bit sized float/int operation in a block. void postProcessType(const Instruction&, spv::Id typeId); + // move OpSampledImage instructions to be next to their users. + void postProcessSamplers(); void dump(std::vector&) const; @@ -870,6 +873,8 @@ class Builder { // Check if the builder is generating code for spec constants. bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; } + void setUseReplicatedComposites(bool use) { useReplicatedComposites = use; } + protected: Id makeIntConstant(Id typeId, unsigned value, bool specConstant); Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant); @@ -936,6 +941,7 @@ class Builder { Id uniqueId; Function* entryPointFunction; bool generatingOpCodeForSpecConst; + bool useReplicatedComposites { false }; AccessChain accessChain; // special blocks of instructions for output diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/SpvPostProcess.cpp b/libs/bgfx/3rdparty/glslang/SPIRV/SpvPostProcess.cpp index ebc6912..5b3fbb5 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/SpvPostProcess.cpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/SpvPostProcess.cpp @@ -483,6 +483,58 @@ void Builder::postProcessFeatures() { } } +// SPIR-V requires that any instruction consuming the result of an OpSampledImage +// be in the same block as the OpSampledImage instruction. This pass goes finds +// uses of OpSampledImage where that is not the case and duplicates the +// OpSampledImage to be immediately before the instruction that consumes it. +// The old OpSampledImage is left in place, potentially with no users. +void Builder::postProcessSamplers() +{ + // first, find all OpSampledImage instructions and store them in a map. + std::map sampledImageInstrs; + for (auto f: module.getFunctions()) { + for (auto b: f->getBlocks()) { + for (auto &i: b->getInstructions()) { + if (i->getOpCode() == spv::OpSampledImage) { + sampledImageInstrs[i->getResultId()] = i.get(); + } + } + } + } + // next find all uses of the given ids and rewrite them if needed. + for (auto f: module.getFunctions()) { + for (auto b: f->getBlocks()) { + auto &instrs = b->getInstructions(); + for (size_t idx = 0; idx < instrs.size(); idx++) { + Instruction *i = instrs[idx].get(); + for (int opnum = 0; opnum < i->getNumOperands(); opnum++) { + // Is this operand of the current instruction the result of an OpSampledImage? + if (i->isIdOperand(opnum) && + sampledImageInstrs.count(i->getIdOperand(opnum))) + { + Instruction *opSampImg = sampledImageInstrs[i->getIdOperand(opnum)]; + if (i->getBlock() != opSampImg->getBlock()) { + Instruction *newInstr = new Instruction(getUniqueId(), + opSampImg->getTypeId(), + spv::OpSampledImage); + newInstr->addIdOperand(opSampImg->getIdOperand(0)); + newInstr->addIdOperand(opSampImg->getIdOperand(1)); + newInstr->setBlock(b); + + // rewrite the user of the OpSampledImage to use the new instruction. + i->setIdOperand(opnum, newInstr->getResultId()); + // insert the new OpSampledImage right before the current instruction. + instrs.insert(instrs.begin() + idx, + std::unique_ptr(newInstr)); + idx++; + } + } + } + } + } + } +} + // comment in header void Builder::postProcess(bool compileOnly) { @@ -491,6 +543,7 @@ void Builder::postProcess(bool compileOnly) postProcessCFG(); postProcessFeatures(); + postProcessSamplers(); } }; // end spv namespace diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/disassemble.cpp b/libs/bgfx/3rdparty/glslang/SPIRV/disassemble.cpp index 2a368b2..ab77610 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/disassemble.cpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/disassemble.cpp @@ -80,6 +80,7 @@ enum ExtInstSet { GLSLextNVInst, OpenCLExtInst, NonSemanticDebugPrintfExtInst, + NonSemanticDebugBreakExtInst, NonSemanticShaderDebugInfo100 }; @@ -506,6 +507,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, extInstSet = OpenCLExtInst; } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) { extInstSet = NonSemanticDebugPrintfExtInst; + } else if (strcmp("NonSemantic.DebugBreak", name) == 0) { + extInstSet = NonSemanticDebugBreakExtInst; } else if (strcmp("NonSemantic.Shader.DebugInfo.100", name) == 0) { extInstSet = NonSemanticShaderDebugInfo100; } else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 || @@ -533,6 +536,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; } else if (extInstSet == NonSemanticDebugPrintfExtInst) { out << "(DebugPrintf)"; + } else if (extInstSet == NonSemanticDebugBreakExtInst) { + out << "(DebugBreak)"; } else if (extInstSet == NonSemanticShaderDebugInfo100) { out << "(" << NonSemanticShaderDebugInfo100GetDebugNames(entrypoint) << ")"; } diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/doc.cpp b/libs/bgfx/3rdparty/glslang/SPIRV/doc.cpp index 4ed6acf..0105caa 100755 --- a/libs/bgfx/3rdparty/glslang/SPIRV/doc.cpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/doc.cpp @@ -319,6 +319,7 @@ const char* DecorationString(int decoration) case DecorationWeightTextureQCOM: return "DecorationWeightTextureQCOM"; case DecorationBlockMatchTextureQCOM: return "DecorationBlockMatchTextureQCOM"; + case DecorationBlockMatchSamplerQCOM: return "DecorationBlockMatchSamplerQCOM"; case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; case DecorationPassthroughNV: return "PassthroughNV"; @@ -1034,6 +1035,8 @@ const char* CapabilityString(int info) case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case CapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT"; @@ -1063,6 +1066,9 @@ const char* CapabilityString(int info) case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + + case CapabilityReplicatedCompositesEXT: return "CapabilityReplicatedCompositesEXT"; default: return "Bad"; } @@ -1441,6 +1447,7 @@ const char* OpcodeString(int op) case 4429: return "OpSubgroupAnyKHR"; case 4430: return "OpSubgroupAllEqualKHR"; case 4432: return "OpSubgroupReadInvocationKHR"; + case 4433: return "OpExtInstWithForwardRefsKHR"; case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; @@ -1577,6 +1584,14 @@ const char* OpcodeString(int op) case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + + case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; default: return "Bad"; @@ -1884,6 +1899,10 @@ void Parameterize() InstructionDesc[OpExtInst].operands.push(OperandLiteralNumber, "'Instruction'"); InstructionDesc[OpExtInst].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n..."); + InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandId, "'Set'"); + InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandLiteralNumber, "'Instruction'"); + InstructionDesc[OpExtInstWithForwardRefsKHR].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n..."); + InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'"); InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true); InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true); @@ -3433,6 +3452,42 @@ void Parameterize() InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'block size'"); InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandImageOperands, "", true); InstructionDesc[OpImageBlockMatchSSDQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchWindowSSDQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchWindowSADQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchGatherSSDQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchGatherSADQCOM].setResultAndType(true, true); + + InstructionDesc[OpConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpSpecConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpCompositeConstructReplicateEXT].operands.push(OperandId, "'Value'"); }); } diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/spirv.hpp b/libs/bgfx/3rdparty/glslang/SPIRV/spirv.hpp index acd4521..38af7fc 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/spirv.hpp +++ b/libs/bgfx/3rdparty/glslang/SPIRV/spirv.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2020 The Khronos Group Inc. +// Copyright (c) 2014-2024 The Khronos Group Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and/or associated documentation files (the "Materials"), @@ -174,7 +174,7 @@ enum ExecutionMode { ExecutionModeStencilRefUnchangedBackAMD = 5082, ExecutionModeStencilRefGreaterBackAMD = 5083, ExecutionModeStencilRefLessBackAMD = 5084, - ExecutionModeQuadDerivativesKHR = 5088, + ExecutionModeQuadDerivativesKHR = 5088, ExecutionModeRequireFullQuadsKHR = 5089, ExecutionModeOutputLinesEXT = 5269, ExecutionModeOutputLinesNV = 5269, @@ -518,6 +518,7 @@ enum Decoration { DecorationNoUnsignedWrap = 4470, DecorationWeightTextureQCOM = 4487, DecorationBlockMatchTextureQCOM = 4488, + DecorationBlockMatchSamplerQCOM = 4499, DecorationExplicitInterpAMD = 4999, DecorationOverrideCoverageNV = 5248, DecorationPassthroughNV = 5250, @@ -725,8 +726,6 @@ enum BuiltIn { BuiltInHitTriangleVertexPositionsKHR = 5335, BuiltInHitMicroTriangleVertexPositionsNV = 5337, BuiltInHitMicroTriangleVertexBarycentricsNV = 5344, - BuiltInHitKindFrontFacingMicroTriangleNV = 5405, - BuiltInHitKindBackFacingMicroTriangleNV = 5406, BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, BuiltInRayGeometryIndexKHR = 5352, @@ -734,6 +733,8 @@ enum BuiltIn { BuiltInSMCountNV = 5375, BuiltInWarpIDNV = 5376, BuiltInSMIDNV = 5377, + BuiltInHitKindFrontFacingMicroTriangleNV = 5405, + BuiltInHitKindBackFacingMicroTriangleNV = 5406, BuiltInCullMaskKHR = 6021, BuiltInMax = 0x7fffffff, }; @@ -1001,6 +1002,7 @@ enum Capability { CapabilityTileImageColorReadAccessEXT = 4166, CapabilityTileImageDepthReadAccessEXT = 4167, CapabilityTileImageStencilReadAccessEXT = 4168, + CapabilityCooperativeMatrixLayoutsARM = 4201, CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, @@ -1035,6 +1037,7 @@ enum Capability { CapabilityTextureSampleWeightedQCOM = 4484, CapabilityTextureBoxFilterQCOM = 4485, CapabilityTextureBlockMatchQCOM = 4486, + CapabilityTextureBlockMatch2QCOM = 4498, CapabilityFloat16ImageAMD = 5008, CapabilityImageGatherBiasLodAMD = 5009, CapabilityFragmentMaskAMD = 5010, @@ -1103,12 +1106,12 @@ enum Capability { CapabilityDemoteToHelperInvocation = 5379, CapabilityDemoteToHelperInvocationEXT = 5379, CapabilityDisplacementMicromapNV = 5380, - CapabilityRayTracingDisplacementMicromapNV = 5409, CapabilityRayTracingOpacityMicromapEXT = 5381, CapabilityShaderInvocationReorderNV = 5383, CapabilityBindlessTextureNV = 5390, CapabilityRayQueryPositionFetchKHR = 5391, CapabilityAtomicFloat16VectorNV = 5404, + CapabilityRayTracingDisplacementMicromapNV = 5409, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, @@ -1161,6 +1164,7 @@ enum Capability { CapabilityDotProductKHR = 6019, CapabilityRayCullMaskKHR = 6020, CapabilityCooperativeMatrixKHR = 6022, + CapabilityReplicatedCompositesEXT = 6024, CapabilityBitInstructions = 6025, CapabilityGroupNonUniformRotateKHR = 6026, CapabilityAtomicFloat32AddEXT = 6033, @@ -1299,6 +1303,8 @@ enum CooperativeMatrixOperandsMask { enum CooperativeMatrixLayout { CooperativeMatrixLayoutRowMajorKHR = 0, CooperativeMatrixLayoutColumnMajorKHR = 1, + CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202, + CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203, CooperativeMatrixLayoutMax = 0x7fffffff, }; @@ -1665,6 +1671,7 @@ enum Op { OpSubgroupAllEqualKHR = 4430, OpGroupNonUniformRotateKHR = 4431, OpSubgroupReadInvocationKHR = 4432, + OpExtInstWithForwardRefsKHR = 4433, OpTraceRayKHR = 4445, OpExecuteCallableKHR = 4446, OpConvertUToAccelerationStructureKHR = 4447, @@ -1687,6 +1694,9 @@ enum Op { OpCooperativeMatrixStoreKHR = 4458, OpCooperativeMatrixMulAddKHR = 4459, OpCooperativeMatrixLengthKHR = 4460, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, OpTypeRayQueryKHR = 4472, OpRayQueryInitializeKHR = 4473, OpRayQueryTerminateKHR = 4474, @@ -1698,6 +1708,10 @@ enum Op { OpImageBoxFilterQCOM = 4481, OpImageBlockMatchSSDQCOM = 4482, OpImageBlockMatchSADQCOM = 4483, + OpImageBlockMatchWindowSSDQCOM = 4500, + OpImageBlockMatchWindowSADQCOM = 4501, + OpImageBlockMatchGatherSSDQCOM = 4502, + OpImageBlockMatchGatherSADQCOM = 4503, OpGroupIAddNonUniformAMD = 5000, OpGroupFAddNonUniformAMD = 5001, OpGroupFMinNonUniformAMD = 5002, @@ -2381,12 +2395,11 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; case OpCopyLogical: *hasResult = true; *hasResultType = true; break; case OpPtrEqual: *hasResult = true; *hasResultType = true; break; case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break; case OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; case OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; case OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; @@ -2414,6 +2427,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break; case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; @@ -2425,6 +2441,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchWindowSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchGatherSADQCOM: *hasResult = true; *hasResultType = true; break; case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; @@ -2436,6 +2456,8 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadAllKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadAnyKHR: *hasResult = true; *hasResultType = true; break; case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; diff --git a/libs/bgfx/3rdparty/glslang/SPIRV/spvIR.h b/libs/bgfx/3rdparty/glslang/SPIRV/spvIR.h index 6f3124f..bd639d8 100644 --- a/libs/bgfx/3rdparty/glslang/SPIRV/spvIR.h +++ b/libs/bgfx/3rdparty/glslang/SPIRV/spvIR.h @@ -97,12 +97,24 @@ class Instruction { Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { } explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { } virtual ~Instruction() {} + void reserveOperands(size_t count) { + operands.reserve(count); + idOperand.reserve(count); + } void addIdOperand(Id id) { // ids can't be 0 assert(id); operands.push_back(id); idOperand.push_back(true); } + // This method is potentially dangerous as it can break assumptions + // about SSA and lack of forward references. + void setIdOperand(unsigned idx, Id id) { + assert(id); + assert(idOperand[idx]); + operands[idx] = id; + } + void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); idOperand.push_back(false); @@ -234,7 +246,7 @@ class Block { void addLocalVariable(std::unique_ptr inst) { localVariables.push_back(std::move(inst)); } const std::vector& getPredecessors() const { return predecessors; } const std::vector& getSuccessors() const { return successors; } - const std::vector >& getInstructions() const { + std::vector >& getInstructions() { return instructions; } const std::vector >& getLocalVariables() const { return localVariables; } @@ -398,6 +410,7 @@ class Function { void setDebugLineInfo(Id fileName, int line, int column) { lineInstruction = std::unique_ptr{new Instruction(OpLine)}; + lineInstruction->reserveOperands(3); lineInstruction->addIdOperand(fileName); lineInstruction->addImmediateOperand(line); lineInstruction->addImmediateOperand(column); @@ -521,6 +534,7 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam linkType(linkage) { // OpFunction + functionInstruction.reserveOperands(2); functionInstruction.addImmediateOperand(FunctionControlMaskNone); functionInstruction.addIdOperand(functionType); parent.mapInstruction(&functionInstruction); diff --git a/libs/bgfx/3rdparty/glslang/StandAlone/StandAlone.cpp b/libs/bgfx/3rdparty/glslang/StandAlone/StandAlone.cpp index ed3decc..ac967f2 100644 --- a/libs/bgfx/3rdparty/glslang/StandAlone/StandAlone.cpp +++ b/libs/bgfx/3rdparty/glslang/StandAlone/StandAlone.cpp @@ -182,6 +182,7 @@ bool HlslEnable16BitTypes = false; bool HlslDX9compatible = false; bool HlslDxPositionW = false; bool EnhancedMsgs = false; +bool AbsolutePath = false; bool DumpBuiltinSymbols = false; std::vector IncludeDirectoryList; @@ -727,6 +728,8 @@ void ProcessArguments(std::vector>& workItem HlslDxPositionW = true; } else if (lowerword == "enhanced-msgs") { EnhancedMsgs = true; + } else if (lowerword == "absolute-path") { + AbsolutePath = true; } else if (lowerword == "auto-sampled-textures") { autoSampledTextures = true; } else if (lowerword == "invert-y" || // synonyms @@ -1159,6 +1162,8 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable); if (EnhancedMsgs) messages = (EShMessages)(messages | EShMsgEnhanced); + if (AbsolutePath) + messages = (EShMessages)(messages | EShMsgAbsolutePath); } // @@ -1190,6 +1195,7 @@ void CompileShaders(glslang::TWorklist& worklist) if (compiler == nullptr) return; + CompileFile(workItem->name.c_str(), compiler); if (! (Options & EOptionSuppressInfolog)) @@ -1878,7 +1884,7 @@ void CompileFile(const char* fileName, ShHandle compiler) for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) { // ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages); ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, GetResources(), 0, - (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages); + (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages, fileName); // const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err", // "or should be l", "ine 1", "string 5\n", "float glo", "bal", // ";\n#error should be line 2\n void main() {", "global = 2.3;}" }; @@ -1993,6 +1999,7 @@ void usage() " without explicit bindings\n" " --auto-map-locations | --aml automatically locate input/output lacking\n" " 'location' (fragile, not cross stage)\n" + " --absolute-path Prints absolute path for messages\n" " --auto-sampled-textures Removes sampler variables and converts\n" " existing textures to sampled textures\n" " --client {vulkan|opengl} see -V and -G\n" @@ -2160,6 +2167,20 @@ char* ReadFileData(const char* fileName) fseek(in, 0, SEEK_SET); + if (count > 3) { + unsigned char head[3]; + if (fread(head, 1, 3, in) == 3) { + if (head[0] == 0xef && head[1] == 0xbb && head[2] == 0xbf) { + // skip BOM + count -= 3; + } else { + fseek(in, 0, SEEK_SET); + } + } else { + Error("can't read input file"); + } + } + char* return_data = (char*)malloc(count + 1); // freed in FreeFileData() if ((int)fread(return_data, 1, count, in) != count) { free(return_data); diff --git a/libs/bgfx/3rdparty/glslang/build_info.h b/libs/bgfx/3rdparty/glslang/build_info.h index ffb33ca..c9d5a91 100644 --- a/libs/bgfx/3rdparty/glslang/build_info.h +++ b/libs/bgfx/3rdparty/glslang/build_info.h @@ -35,7 +35,7 @@ #define GLSLANG_BUILD_INFO #define GLSLANG_VERSION_MAJOR 14 -#define GLSLANG_VERSION_MINOR 0 +#define GLSLANG_VERSION_MINOR 2 #define GLSLANG_VERSION_PATCH 0 #define GLSLANG_VERSION_FLAVOR "" diff --git a/libs/bgfx/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp b/libs/bgfx/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp index 870698f..cea965d 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/CInterface/glslang_c_interface.cpp @@ -205,6 +205,7 @@ static int c_shader_messages(glslang_messages_t messages) CONVERT_MSG(GLSLANG_MSG_HLSL_LEGALIZATION_BIT, EShMsgHlslLegalization); CONVERT_MSG(GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT, EShMsgHlslDX9Compatible); CONVERT_MSG(GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT, EShMsgBuiltinSymbolTable); + CONVERT_MSG(GLSLANG_MSG_ABSOLUTE_PATH, EShMsgAbsolutePath); return res; #undef CONVERT_MSG } diff --git a/libs/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp b/libs/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp index 74c9c1d..0fd724d 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/HLSL/hlslParseHelper.cpp @@ -962,14 +962,11 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt return addConstructor(loc, base, type); } } - if (base->getVectorSize() == 1) { + // Use EOpIndexDirect (below) with vec1.x so that it remains l-value (Test/hlsl.swizzle.vec1.comp) + if (base->getVectorSize() == 1 && selectors.size() > 1) { TType scalarType(base->getBasicType(), EvqTemporary, 1); - if (selectors.size() == 1) - return addConstructor(loc, base, scalarType); - else { - TType vectorType(base->getBasicType(), EvqTemporary, selectors.size()); - return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType); - } + TType vectorType(base->getBasicType(), EvqTemporary, selectors.size()); + return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType); } if (base->getType().getQualifier().isFrontEndConstant()) @@ -9658,6 +9655,10 @@ void HlslParseContext::correctOutput(TQualifier& qualifier) if (language != EShLangTessControl) qualifier.patch = false; + // Fixes Test/hlsl.entry-inout.vert (SV_Position will not become a varying). + if (qualifier.builtIn == EbvNone) + qualifier.builtIn = qualifier.declaredBuiltIn; + switch (qualifier.builtIn) { case EbvFragDepth: intermediate.setDepthReplacing(); diff --git a/libs/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h b/libs/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h index 64bffa8..0ac526b 100755 --- a/libs/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Include/BaseTypes.h @@ -268,7 +268,6 @@ enum TBuiltInVariable { EbvRayTmin, EbvRayTmax, EbvCullMask, - EbvHitT, EbvHitKind, EbvObjectToWorld, EbvObjectToWorld3x4, @@ -495,7 +494,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvObjectRayDirection: return "ObjectRayDirectionNV"; case EbvRayTmin: return "ObjectRayTminNV"; case EbvRayTmax: return "ObjectRayTmaxNV"; - case EbvHitT: return "HitTNV"; case EbvHitKind: return "HitKindNV"; case EbvIncomingRayFlags: return "IncomingRayFlagsNV"; case EbvObjectToWorld: return "ObjectToWorldNV"; diff --git a/libs/bgfx/3rdparty/glslang/glslang/Include/InfoSink.h b/libs/bgfx/3rdparty/glslang/glslang/Include/InfoSink.h index dceb603..23f495d 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/Include/InfoSink.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Include/InfoSink.h @@ -36,6 +36,7 @@ #define _INFOSINK_INCLUDED_ #include "../Include/Common.h" +#include #include namespace glslang { @@ -67,7 +68,7 @@ enum TOutputStream { // class TInfoSinkBase { public: - TInfoSinkBase() : outputStream(4) {} + TInfoSinkBase() : outputStream(4), shaderFileName(nullptr) {} void erase() { sink.erase(); } TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; } TInfoSinkBase& operator<<(char c) { append(1, c); return *this; } @@ -94,11 +95,22 @@ class TInfoSinkBase { default: append("UNKNOWN ERROR: "); break; } } - void location(const TSourceLoc& loc) { + void location(const TSourceLoc& loc, bool absolute = false) { const int maxSize = 24; char locText[maxSize]; snprintf(locText, maxSize, ":%d", loc.line); - append(loc.getStringNameOrNum(false).c_str()); + + if(loc.getFilename() == nullptr && shaderFileName != nullptr && absolute) { + append(std::filesystem::absolute(shaderFileName).string()); + } else { + std::string location = loc.getStringNameOrNum(false); + if (absolute) { + append(std::filesystem::absolute(location).string()); + } else { + append(location); + } + } + append(locText); append(": "); } @@ -119,6 +131,11 @@ class TInfoSinkBase { outputStream = output; } + void setShaderFileName(const char* file = nullptr) + { + shaderFileName = file; + } + protected: void append(const char* s); @@ -131,6 +148,7 @@ class TInfoSinkBase { void appendToStream(const char* s); TPersistString sink; int outputStream; + const char* shaderFileName; }; } // end namespace glslang diff --git a/libs/bgfx/3rdparty/glslang/glslang/Include/Types.h b/libs/bgfx/3rdparty/glslang/glslang/Include/Types.h index f938f11..2326228 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/Include/Types.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Include/Types.h @@ -573,7 +573,8 @@ class TQualifier { } const char* semanticName; - TStorageQualifier storage : 6; + TStorageQualifier storage : 7; + static_assert(EvqLast < 64, "need to increase size of TStorageQualifier bitfields!"); TBuiltInVariable builtIn : 9; TBuiltInVariable declaredBuiltIn : 9; static_assert(EbvLast < 256, "need to increase size of TBuiltInVariable bitfields!"); @@ -1434,13 +1435,25 @@ class TTypeParameters { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr) {} + TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr), spirvType(nullptr) {} TBasicType basicType; TArraySizes *arraySizes; + TSpirvType *spirvType; - bool operator==(const TTypeParameters& rhs) const { return basicType == rhs.basicType && *arraySizes == *rhs.arraySizes; } - bool operator!=(const TTypeParameters& rhs) const { return basicType != rhs.basicType || *arraySizes != *rhs.arraySizes; } + bool operator==(const TTypeParameters& rhs) const + { + bool same = basicType == rhs.basicType && *arraySizes == *rhs.arraySizes; + if (same && basicType == EbtSpirvType) { + assert(spirvType && rhs.spirvType); + return *spirvType == *rhs.spirvType; + } + return same; + } + bool operator!=(const TTypeParameters& rhs) const + { + return !(*this == rhs); + } }; // @@ -1617,6 +1630,10 @@ class TType { } if (p.isCoopmatKHR() && p.typeParameters && p.typeParameters->arraySizes->getNumDims() > 0) { basicType = p.typeParameters->basicType; + if (isSpirvType()) { + assert(p.typeParameters->spirvType); + spirvType = p.typeParameters->spirvType; + } if (p.typeParameters->arraySizes->getNumDims() == 4) { const int dimSize = p.typeParameters->arraySizes->getDimSize(3); @@ -2718,7 +2735,8 @@ class TType { if (isCoopMatKHR() && right.isCoopMatKHR()) { return ((getBasicType() == right.getBasicType()) || (getBasicType() == EbtCoopmat) || (right.getBasicType() == EbtCoopmat)) && - typeParameters == nullptr && right.typeParameters != nullptr; + ((typeParameters == nullptr && right.typeParameters != nullptr) || + (typeParameters != nullptr && right.typeParameters == nullptr)); } return false; } @@ -2824,6 +2842,7 @@ class TType { typeParameters = new TTypeParameters; typeParameters->arraySizes = new TArraySizes; *typeParameters->arraySizes = *copyOf.typeParameters->arraySizes; + *typeParameters->spirvType = *copyOf.typeParameters->spirvType; typeParameters->basicType = copyOf.basicType; } diff --git a/libs/bgfx/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h b/libs/bgfx/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h index 9bc2114..51f5642 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Include/glslang_c_shader_types.h @@ -157,23 +157,24 @@ typedef enum { /* EShMessages counterpart */ typedef enum { - GLSLANG_MSG_DEFAULT_BIT = 0, - GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0), - GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1), - GLSLANG_MSG_AST_BIT = (1 << 2), - GLSLANG_MSG_SPV_RULES_BIT = (1 << 3), - GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4), - GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5), - GLSLANG_MSG_READ_HLSL_BIT = (1 << 6), - GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7), - GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8), - GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9), - GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10), + GLSLANG_MSG_DEFAULT_BIT = 0, + GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0), + GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1), + GLSLANG_MSG_AST_BIT = (1 << 2), + GLSLANG_MSG_SPV_RULES_BIT = (1 << 3), + GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4), + GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5), + GLSLANG_MSG_READ_HLSL_BIT = (1 << 6), + GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7), + GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8), + GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9), + GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10), GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11), - GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12), - GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13), - GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), - GLSLANG_MSG_ENHANCED = (1 << 15), + GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12), + GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13), + GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), + GLSLANG_MSG_ENHANCED = (1 << 15), + GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16), LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT), } glslang_messages_t; diff --git a/libs/bgfx/3rdparty/glslang/glslang/Include/intermediate.h b/libs/bgfx/3rdparty/glslang/glslang/Include/intermediate.h index c7640ec..bcce91d 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/Include/intermediate.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Include/intermediate.h @@ -1111,6 +1111,12 @@ enum TOperator { EOpImageBoxFilterQCOM, EOpImageBlockMatchSADQCOM, EOpImageBlockMatchSSDQCOM, + + // Image processing2 + EOpImageBlockMatchWindowSSDQCOM, + EOpImageBlockMatchWindowSADQCOM, + EOpImageBlockMatchGatherSSDQCOM, + EOpImageBlockMatchGatherSADQCOM, }; enum TLinkType { diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp index 858ae6a..d8a969d 100755 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Initialize.cpp @@ -4233,6 +4233,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 textureBoxFilterQCOM(sampler2D, vec2, vec2);" "vec4 textureBlockMatchSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" "vec4 textureBlockMatchSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + + "vec4 textureBlockMatchWindowSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + "vec4 textureBlockMatchWindowSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + "vec4 textureBlockMatchGatherSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + "vec4 textureBlockMatchGatherSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" "\n"); } @@ -4553,6 +4558,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "const int gl_MatrixOperandsSaturatingAccumulation = 0x10;\n" "const int gl_CooperativeMatrixLayoutRowMajor = 0;\n" "const int gl_CooperativeMatrixLayoutColumnMajor = 1;\n" + "const int gl_CooperativeMatrixLayoutRowBlockedInterleavedARM = 4202;\n" + "const int gl_CooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203;\n" "\n" ); } @@ -8909,10 +8916,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 140)) { + symbolTable.setFunctionExtensions("textureWeightedQCOM", 1, &E_GL_QCOM_image_processing); symbolTable.setFunctionExtensions("textureBoxFilterQCOM", 1, &E_GL_QCOM_image_processing); symbolTable.setFunctionExtensions("textureBlockMatchSADQCOM", 1, &E_GL_QCOM_image_processing); symbolTable.setFunctionExtensions("textureBlockMatchSSDQCOM", 1, &E_GL_QCOM_image_processing); + + symbolTable.setFunctionExtensions("textureBlockMatchWindowSSDQCOM", 1, &E_GL_QCOM_image_processing2); + symbolTable.setFunctionExtensions("textureBlockMatchWindowSADQCOM", 1, &E_GL_QCOM_image_processing2); + symbolTable.setFunctionExtensions("textureBlockMatchGatherSSDQCOM", 1, &E_GL_QCOM_image_processing2); + symbolTable.setFunctionExtensions("textureBlockMatchGatherSADQCOM", 1, &E_GL_QCOM_image_processing2); } break; @@ -9198,8 +9211,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable); BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable); BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable); - BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable); - BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable); BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable); BuiltInVariable("gl_HitKindEXT", EbvHitKind, symbolTable); BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorld, symbolTable); @@ -9218,6 +9229,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_HitKindFrontFacingMicroTriangleNV", EbvHitKindFrontFacingMicroTriangleNV, symbolTable); BuiltInVariable("gl_HitKindBackFacingMicroTriangleNV", EbvHitKindBackFacingMicroTriangleNV, symbolTable); + // gl_HitT variables are aliases of their gl_RayTmax counterparts. + RetargetVariable("gl_HitTNV", "gl_RayTmaxNV", symbolTable); + RetargetVariable("gl_HitTEXT", "gl_RayTmaxEXT", symbolTable); + // GL_ARB_shader_ballot symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot); @@ -10117,6 +10132,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("textureBoxFilterQCOM", EOpImageBoxFilterQCOM); symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM); symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM); + + symbolTable.relateToOperator("textureBlockMatchWindowSSDQCOM", EOpImageBlockMatchWindowSSDQCOM); + symbolTable.relateToOperator("textureBlockMatchWindowSADQCOM", EOpImageBlockMatchWindowSADQCOM); + symbolTable.relateToOperator("textureBlockMatchGatherSSDQCOM", EOpImageBlockMatchGatherSSDQCOM); + symbolTable.relateToOperator("textureBlockMatchGatherSADQCOM", EOpImageBlockMatchGatherSADQCOM); } if (profile != EEsProfile && spvVersion.spv == 0) { diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp index 6e3d088..591dfc7 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -59,7 +59,7 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args); infoSink.info.prefix(prefix); - infoSink.info.location(loc); + infoSink.info.location(loc, messages & EShMsgAbsolutePath); infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n"; if (prefix == EPrefixError) { diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp index f6503ec..98a7d26 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -399,6 +399,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& if (spvVersion.spv < glslang::EShTargetSpv_1_3) error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", ""); intermediate.setUseVariablePointers(); + } else if (spvVersion.spv > 0 && tokens[0].compare("use_replicated_composites") == 0) { + if (tokens.size() != 1) + error(loc, "extra tokens", "#pragma", ""); + intermediate.setReplicatedComposites(); } else if (tokens[0].compare("once") == 0) { warn(loc, "not implemented", "#pragma once", ""); } else if (tokens[0].compare("glslang_binary_double_output") == 0) { @@ -492,7 +496,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if ((variable->getMangledName() == "gl_PrimitiveTriangleIndicesEXT" && primitiveType != ElgTriangles) || (variable->getMangledName() == "gl_PrimitiveLineIndicesEXT" && primitiveType != ElgLines) || (variable->getMangledName() == "gl_PrimitivePointIndicesEXT" && primitiveType != ElgPoints)) { - error(loc, "cannot be used (ouput primitive type mismatch)", string->c_str(), ""); + error(loc, "cannot be used (output primitive type mismatch)", string->c_str(), ""); variable = nullptr; } } @@ -598,6 +602,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn indexValue >= resources.maxCullDistances) { error(loc, "gl_CullDistance", "[", "array index out of range '%d'", indexValue); } + else if (base->getQualifier().builtIn == EbvSampleMask && + indexValue >= (resources.maxSamples + 31) / 32) { + error(loc, "gl_SampleMask", "[", "array index out of range '%d'", indexValue); + } // For 2D per-view builtin arrays, update the inner dimension size in parent type if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) { TIntermBinary* binaryNode = base->getAsBinaryNode(); @@ -2700,7 +2708,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan case EOpEmitStreamVertex: case EOpEndStreamPrimitive: if (version == 150) - requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5"); + requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the version is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5"); intermediate.setMultiStream(); break; @@ -3609,6 +3617,19 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T makeSpecConst = ! intArgument && !type.isArray(); break; + case EOpConstructCooperativeMatrixNV: + case EOpConstructCooperativeMatrixKHR: + case EOpConstructStruct: + { + const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites }; + if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) { + makeSpecConst = true; + } else { + makeSpecConst = false; + } + } + break; + default: // anything else wasn't white-listed in the spec as a conversion makeSpecConst = false; @@ -6564,10 +6585,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision); if (repeated >= 0 && ! typeCollision) error(loc, "overlapping use of location", "location", "%d", repeated); - // "fragment-shader outputs/tileImageEXT ... if two variables are placed within the same - // location, they must have the same underlying type (floating-point or integer)" - if (typeCollision && language == EShLangFragment && (qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT)) - error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated); + // When location aliasing, the aliases sharing the location must have the same underlying numerical type and bit width( + // floating - point or integer, 32 - bit versus 64 - bit,etc.) + if (typeCollision && (qualifier.isPipeInput() || qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT)) + error(loc, "the aliases sharing the location", "location", "%d must be the same basic type and interpolation qualification", repeated); } if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) { @@ -7413,6 +7434,7 @@ void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPub case EbtUint: case EbtUint8: case EbtUint16: + case EbtSpirvType: break; default: error(loc, "coopmat invalid basic type", TType::getBasicString(publicType.typeParameters->basicType), ""); @@ -7636,6 +7658,7 @@ struct AccessChainTraverser : public TIntermTraverser { {} TString path = ""; + TStorageQualifier topLevelStorageQualifier = TStorageQualifier::EvqLast; bool visitBinary(TVisit, TIntermBinary* binary) override { if (binary->getOp() == EOpIndexDirectStruct) @@ -7666,6 +7689,8 @@ struct AccessChainTraverser : public TIntermTraverser { } void visitSymbol(TIntermSymbol* symbol) override { + if (symbol->getType().isOpaque()) + topLevelStorageQualifier = symbol->getQualifier().storage; if (!IsAnonymous(symbol->getName())) path.append(symbol->getName()); } @@ -7676,6 +7701,15 @@ TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc AccessChainTraverser accessChainTraverser{}; intermTyped->traverse(&accessChainTraverser); + if (accessChainTraverser.topLevelStorageQualifier == TStorageQualifier::EvqUniform) + { + TParameter param = { 0, new TType, {} }; + param.type->shallowCopy(intermTyped->getType()); + + function->addParameter(param); + return intermTyped; + } + TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType, {} }; param.type->shallowCopy(intermTyped->getType()); @@ -7795,7 +7829,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden error(loc, "unexpected number type parameters", identifier.c_str(), ""); } if (publicType.typeParameters) { - if (!isTypeFloat(publicType.typeParameters->basicType) && !isTypeInt(publicType.typeParameters->basicType)) { + if (!isTypeFloat(publicType.typeParameters->basicType) && + !isTypeInt(publicType.typeParameters->basicType) && publicType.typeParameters->basicType != EbtSpirvType) { error(loc, "expected 8, 16, 32, or 64 bit signed or unsigned integer or 16, 32, or 64 bit float type", identifier.c_str(), ""); } } @@ -8337,6 +8372,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* int paramCount = 0; // keeps track of the constructor parameter number being checked + // We don't know "top down" whether type is a specialization constant, + // but a const becomes a specialization constant if any of its children are. + bool hasSpecConst = false; + bool isConstConstructor = true; + // for each parameter to the constructor call, check to see if the right type is passed or convert them // to the right type if possible (and allowed). // for structure constructors, just check if the right type is passed, no conversion is allowed. @@ -8349,13 +8389,24 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* else newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true); - if (newNode) + if (newNode) { *p = newNode; - else + if (!newNode->getType().getQualifier().isConstant()) + isConstConstructor = false; + if (newNode->getType().getQualifier().isSpecConstant()) + hasSpecConst = true; + } else return nullptr; } - TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc); + TIntermTyped* ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc); + + const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites }; + if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) { + if (isConstConstructor && hasSpecConst) { + ret_node->getWritableType().getQualifier().makeSpecConstant(); + } + } TIntermAggregate *agg_node = ret_node->getAsAggregate(); if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix())) diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp index a793a5d..034a030 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -788,7 +788,7 @@ bool ProcessDeferred( // set version/profile to defaultVersion/defaultProfile regardless of the #version // directive in the source code bool forceDefaultVersionAndProfile, - int overrideVersion, // overrides version specified by #verison or default version + int overrideVersion, // overrides version specified by #version or default version bool forwardCompatible, // give errors for use of deprecated features EShMessages messages, // warnings/errors/AST; things to print out TIntermediate& intermediate, // returned tree, etc. @@ -1434,7 +1434,8 @@ int ShCompile( int /*debugOptions*/, int defaultVersion, // use 100 for ES environment, 110 for desktop bool forwardCompatible, // give errors for use of deprecated features - EShMessages messages // warnings/errors/AST; things to print out + EShMessages messages, // warnings/errors/AST; things to print out, + const char *shaderFileName // the filename ) { // Map the generic handle to the C++ object @@ -1450,6 +1451,9 @@ int ShCompile( compiler->infoSink.info.erase(); compiler->infoSink.debug.erase(); + compiler->infoSink.info.setShaderFileName(shaderFileName); + compiler->infoSink.debug.setShaderFileName(shaderFileName); + TIntermediate intermediate(compiler->getLanguage()); TShader::ForbidIncluder includer; @@ -2101,6 +2105,8 @@ const char* TProgram::getInfoDebugLog() // Reflection implementation. // +unsigned int TObjectReflection::layoutLocation() const { return type->getQualifier().layoutLocation; } + bool TProgram::buildReflection(int opts) { if (! linked || reflection != nullptr) diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp index 4019371..e016ef6 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.cpp @@ -264,11 +264,15 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_fragment_shader_barycentric] = EBhDisable; extensionBehavior[E_GL_EXT_expect_assume] = EBhDisable; + extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable; + extensionBehavior[E_GL_EXT_spec_constant_composites] = EBhDisable; + extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable; // #line and #include extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable; + extensionBehavior[E_GL_ARB_shading_language_include] = EBhDisable; extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable; extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable; @@ -312,6 +316,7 @@ void TParseVersions::initializeExtensionBehavior() // QCOM extensionBehavior[E_GL_QCOM_image_processing] = EBhDisable; + extensionBehavior[E_GL_QCOM_image_processing2] = EBhDisable; // AEP extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; @@ -443,6 +448,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_QCOM_image_processing 1\n" + "#define GL_QCOM_image_processing2 1\n" ; if (version >= 300) { @@ -514,6 +520,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_fragment_shading_rate 1\n" "#define GL_EXT_shared_memory_block 1\n" "#define GL_EXT_shader_integer_mix 1\n" + "#define GL_EXT_spec_constant_composites 1\n" // GL_KHR_shader_subgroup "#define GL_KHR_shader_subgroup_basic 1\n" @@ -569,6 +576,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_NV_shader_invocation_reorder 1\n" "#define GL_QCOM_image_processing 1\n" + "#define GL_QCOM_image_processing2 1\n" "#define GL_EXT_shader_explicit_arithmetic_types 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n" @@ -590,6 +598,8 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_fragment_shader_barycentric 1\n" "#define GL_EXT_shader_quad_control 1\n" "#define GL_EXT_texture_array 1\n" + + "#define GL_EXT_control_flow_attributes2 1\n" ; if (spvVersion.spv == 0) { @@ -983,6 +993,8 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co updateExtensionBehavior(line, "GL_OES_shader_io_blocks", behaviorString); else if (strcmp(extension, "GL_GOOGLE_include_directive") == 0) updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString); + else if (strcmp(extension, "GL_ARB_shading_language_include") == 0) + updateExtensionBehavior(line, "GL_GOOGLE_cpp_style_line_directive", behaviorString); // subgroup_* to subgroup_basic else if (strcmp(extension, "GL_KHR_shader_subgroup_vote") == 0) updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString); diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h index 70240ff..75a8237 100755 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/Versions.h @@ -221,6 +221,8 @@ const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_insta const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array"; const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence"; const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume"; +const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2"; +const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites"; // Arrays of extensions for the above viewportEXTs duplications @@ -241,6 +243,7 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi // #line and #include const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive"; const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive"; +const char* const E_GL_ARB_shading_language_include = "GL_ARB_shading_language_include"; const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot"; const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax"; @@ -290,6 +293,7 @@ const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]); const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing"; +const char* const E_GL_QCOM_image_processing2 = "GL_QCOM_image_processing2"; // AEP const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y index 0f34e07..53c5767 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang.y @@ -508,7 +508,10 @@ function_call_header_with_parameters && $3->getType().containsOpaque()) { TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument($2.loc, $1.function, $3); - $$.intermNode = parseContext.intermediate.mergeAggregate($1.intermNode, remappedNode, $2.loc); + if (remappedNode == $3) + $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.loc); + else + $$.intermNode = parseContext.intermediate.mergeAggregate($1.intermNode, remappedNode, $2.loc); $$.function = $1.function; } else @@ -1756,6 +1759,7 @@ type_parameter_specifier_list : type_specifier { $$ = new TTypeParameters; $$->arraySizes = new TArraySizes; + $$->spirvType = $1.spirvType; $$->basicType = $1.basicType; } | unary_expression { @@ -3950,7 +3954,8 @@ iteration_statement $$ = $1; } | attribute iteration_statement_nonattributed { - parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); + const char * extensions[2] = { E_GL_EXT_control_flow_attributes, E_GL_EXT_control_flow_attributes2 }; + parseContext.requireExtensions($2->getLoc(), 2, extensions, "attribute"); parseContext.handleLoopAttributes(*$1, $2); $$ = $2; } diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp index 3f09e89..5764d39 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/glslang_tab.cpp @@ -1163,74 +1163,74 @@ static const yytype_int16 yyrline[] = 0, 355, 355, 361, 364, 369, 372, 375, 379, 382, 385, 389, 393, 397, 401, 405, 409, 415, 422, 425, 428, 431, 434, 439, 447, 454, 461, 467, 471, 478, - 481, 487, 505, 527, 535, 540, 567, 575, 581, 585, - 589, 609, 610, 611, 612, 618, 619, 624, 629, 638, - 639, 644, 652, 653, 659, 668, 669, 674, 679, 684, - 692, 693, 702, 714, 715, 724, 725, 734, 735, 744, - 745, 753, 754, 762, 763, 771, 772, 772, 790, 791, - 807, 811, 815, 819, 824, 828, 832, 836, 840, 844, - 848, 855, 858, 869, 876, 881, 888, 893, 898, 905, - 909, 913, 917, 922, 927, 936, 936, 947, 951, 958, - 963, 971, 979, 991, 994, 1001, 1014, 1037, 1060, 1075, - 1100, 1111, 1121, 1131, 1141, 1150, 1153, 1157, 1161, 1166, - 1174, 1179, 1184, 1189, 1194, 1203, 1213, 1240, 1249, 1256, - 1263, 1270, 1277, 1285, 1293, 1303, 1313, 1320, 1330, 1336, - 1339, 1346, 1350, 1354, 1362, 1371, 1374, 1385, 1388, 1391, - 1395, 1399, 1403, 1407, 1410, 1415, 1419, 1424, 1432, 1436, - 1441, 1447, 1453, 1460, 1465, 1470, 1478, 1483, 1495, 1509, - 1515, 1520, 1528, 1536, 1544, 1552, 1560, 1568, 1576, 1584, - 1592, 1599, 1606, 1610, 1615, 1620, 1625, 1630, 1635, 1640, - 1644, 1648, 1652, 1656, 1662, 1668, 1678, 1685, 1688, 1696, - 1703, 1714, 1719, 1727, 1731, 1741, 1744, 1750, 1756, 1761, - 1769, 1779, 1783, 1787, 1791, 1796, 1800, 1805, 1810, 1815, - 1820, 1825, 1830, 1835, 1840, 1845, 1851, 1857, 1863, 1868, - 1873, 1878, 1883, 1888, 1893, 1898, 1903, 1908, 1913, 1918, - 1923, 1930, 1935, 1940, 1945, 1950, 1955, 1960, 1965, 1970, - 1975, 1980, 1985, 1993, 2001, 2009, 2015, 2021, 2027, 2033, - 2039, 2045, 2051, 2057, 2063, 2069, 2075, 2081, 2087, 2093, - 2099, 2105, 2111, 2117, 2123, 2129, 2135, 2141, 2147, 2153, - 2159, 2165, 2171, 2177, 2183, 2189, 2195, 2201, 2207, 2215, - 2223, 2231, 2239, 2247, 2255, 2263, 2271, 2279, 2287, 2295, - 2303, 2309, 2315, 2321, 2327, 2333, 2339, 2345, 2351, 2357, - 2363, 2369, 2375, 2381, 2387, 2393, 2399, 2405, 2411, 2417, - 2423, 2429, 2435, 2441, 2447, 2453, 2459, 2465, 2471, 2477, - 2483, 2489, 2495, 2501, 2507, 2513, 2519, 2523, 2527, 2531, - 2536, 2541, 2546, 2551, 2556, 2561, 2566, 2571, 2576, 2581, - 2586, 2591, 2596, 2601, 2607, 2613, 2619, 2625, 2631, 2637, - 2643, 2649, 2655, 2661, 2667, 2673, 2679, 2684, 2689, 2694, - 2699, 2704, 2709, 2714, 2719, 2724, 2729, 2734, 2739, 2744, - 2749, 2754, 2759, 2764, 2769, 2774, 2779, 2784, 2789, 2794, - 2799, 2804, 2809, 2814, 2819, 2824, 2829, 2834, 2839, 2844, - 2850, 2856, 2861, 2866, 2871, 2877, 2882, 2887, 2892, 2898, - 2903, 2908, 2913, 2919, 2924, 2929, 2934, 2940, 2946, 2952, - 2958, 2963, 2969, 2975, 2981, 2986, 2991, 2996, 3001, 3006, - 3012, 3017, 3022, 3027, 3033, 3038, 3043, 3048, 3054, 3059, - 3064, 3069, 3075, 3080, 3085, 3090, 3096, 3101, 3106, 3111, - 3117, 3122, 3127, 3132, 3138, 3143, 3148, 3153, 3159, 3164, - 3169, 3174, 3180, 3185, 3190, 3195, 3201, 3206, 3211, 3216, - 3222, 3227, 3232, 3237, 3243, 3248, 3253, 3258, 3264, 3269, - 3274, 3279, 3285, 3290, 3295, 3300, 3306, 3311, 3316, 3321, - 3326, 3331, 3336, 3341, 3346, 3351, 3356, 3361, 3366, 3371, - 3376, 3381, 3386, 3391, 3396, 3401, 3406, 3411, 3416, 3421, - 3426, 3432, 3438, 3444, 3450, 3456, 3462, 3468, 3475, 3482, - 3488, 3494, 3500, 3506, 3513, 3520, 3527, 3534, 3538, 3542, - 3547, 3563, 3568, 3573, 3581, 3581, 3598, 3598, 3608, 3611, - 3624, 3646, 3673, 3677, 3683, 3688, 3699, 3702, 3708, 3714, - 3723, 3726, 3732, 3736, 3737, 3743, 3744, 3745, 3746, 3747, - 3748, 3749, 3750, 3754, 3762, 3763, 3767, 3763, 3779, 3780, - 3784, 3784, 3791, 3791, 3805, 3808, 3816, 3824, 3835, 3836, - 3840, 3843, 3850, 3857, 3861, 3869, 3873, 3886, 3889, 3896, - 3896, 3916, 3919, 3925, 3937, 3949, 3952, 3959, 3959, 3974, - 3974, 3992, 3992, 4013, 4016, 4022, 4025, 4031, 4035, 4042, - 4047, 4052, 4059, 4062, 4066, 4070, 4074, 4083, 4087, 4096, - 4099, 4102, 4110, 4110, 4152, 4157, 4160, 4165, 4168, 4173, - 4176, 4181, 4184, 4189, 4192, 4197, 4200, 4205, 4209, 4214, - 4218, 4223, 4227, 4234, 4237, 4242, 4245, 4248, 4251, 4254, - 4259, 4268, 4279, 4284, 4292, 4296, 4301, 4305, 4310, 4314, - 4319, 4323, 4330, 4333, 4338, 4341, 4344, 4347, 4352, 4355, - 4360, 4366, 4369, 4372, 4375, 4380, 4384, 4389, 4393, 4398, - 4402, 4409, 4412, 4417, 4420, 4425, 4428, 4434, 4437, 4442, - 4445 + 481, 487, 505, 530, 538, 543, 570, 578, 584, 588, + 592, 612, 613, 614, 615, 621, 622, 627, 632, 641, + 642, 647, 655, 656, 662, 671, 672, 677, 682, 687, + 695, 696, 705, 717, 718, 727, 728, 737, 738, 747, + 748, 756, 757, 765, 766, 774, 775, 775, 793, 794, + 810, 814, 818, 822, 827, 831, 835, 839, 843, 847, + 851, 858, 861, 872, 879, 884, 891, 896, 901, 908, + 912, 916, 920, 925, 930, 939, 939, 950, 954, 961, + 966, 974, 982, 994, 997, 1004, 1017, 1040, 1063, 1078, + 1103, 1114, 1124, 1134, 1144, 1153, 1156, 1160, 1164, 1169, + 1177, 1182, 1187, 1192, 1197, 1206, 1216, 1243, 1252, 1259, + 1266, 1273, 1280, 1288, 1296, 1306, 1316, 1323, 1333, 1339, + 1342, 1349, 1353, 1357, 1365, 1374, 1377, 1388, 1391, 1394, + 1398, 1402, 1406, 1410, 1413, 1418, 1422, 1427, 1435, 1439, + 1444, 1450, 1456, 1463, 1468, 1473, 1481, 1486, 1498, 1512, + 1518, 1523, 1531, 1539, 1547, 1555, 1563, 1571, 1579, 1587, + 1595, 1602, 1609, 1613, 1618, 1623, 1628, 1633, 1638, 1643, + 1647, 1651, 1655, 1659, 1665, 1671, 1681, 1688, 1691, 1699, + 1706, 1717, 1722, 1730, 1734, 1744, 1747, 1753, 1759, 1765, + 1773, 1783, 1787, 1791, 1795, 1800, 1804, 1809, 1814, 1819, + 1824, 1829, 1834, 1839, 1844, 1849, 1855, 1861, 1867, 1872, + 1877, 1882, 1887, 1892, 1897, 1902, 1907, 1912, 1917, 1922, + 1927, 1934, 1939, 1944, 1949, 1954, 1959, 1964, 1969, 1974, + 1979, 1984, 1989, 1997, 2005, 2013, 2019, 2025, 2031, 2037, + 2043, 2049, 2055, 2061, 2067, 2073, 2079, 2085, 2091, 2097, + 2103, 2109, 2115, 2121, 2127, 2133, 2139, 2145, 2151, 2157, + 2163, 2169, 2175, 2181, 2187, 2193, 2199, 2205, 2211, 2219, + 2227, 2235, 2243, 2251, 2259, 2267, 2275, 2283, 2291, 2299, + 2307, 2313, 2319, 2325, 2331, 2337, 2343, 2349, 2355, 2361, + 2367, 2373, 2379, 2385, 2391, 2397, 2403, 2409, 2415, 2421, + 2427, 2433, 2439, 2445, 2451, 2457, 2463, 2469, 2475, 2481, + 2487, 2493, 2499, 2505, 2511, 2517, 2523, 2527, 2531, 2535, + 2540, 2545, 2550, 2555, 2560, 2565, 2570, 2575, 2580, 2585, + 2590, 2595, 2600, 2605, 2611, 2617, 2623, 2629, 2635, 2641, + 2647, 2653, 2659, 2665, 2671, 2677, 2683, 2688, 2693, 2698, + 2703, 2708, 2713, 2718, 2723, 2728, 2733, 2738, 2743, 2748, + 2753, 2758, 2763, 2768, 2773, 2778, 2783, 2788, 2793, 2798, + 2803, 2808, 2813, 2818, 2823, 2828, 2833, 2838, 2843, 2848, + 2854, 2860, 2865, 2870, 2875, 2881, 2886, 2891, 2896, 2902, + 2907, 2912, 2917, 2923, 2928, 2933, 2938, 2944, 2950, 2956, + 2962, 2967, 2973, 2979, 2985, 2990, 2995, 3000, 3005, 3010, + 3016, 3021, 3026, 3031, 3037, 3042, 3047, 3052, 3058, 3063, + 3068, 3073, 3079, 3084, 3089, 3094, 3100, 3105, 3110, 3115, + 3121, 3126, 3131, 3136, 3142, 3147, 3152, 3157, 3163, 3168, + 3173, 3178, 3184, 3189, 3194, 3199, 3205, 3210, 3215, 3220, + 3226, 3231, 3236, 3241, 3247, 3252, 3257, 3262, 3268, 3273, + 3278, 3283, 3289, 3294, 3299, 3304, 3310, 3315, 3320, 3325, + 3330, 3335, 3340, 3345, 3350, 3355, 3360, 3365, 3370, 3375, + 3380, 3385, 3390, 3395, 3400, 3405, 3410, 3415, 3420, 3425, + 3430, 3436, 3442, 3448, 3454, 3460, 3466, 3472, 3479, 3486, + 3492, 3498, 3504, 3510, 3517, 3524, 3531, 3538, 3542, 3546, + 3551, 3567, 3572, 3577, 3585, 3585, 3602, 3602, 3612, 3615, + 3628, 3650, 3677, 3681, 3687, 3692, 3703, 3706, 3712, 3718, + 3727, 3730, 3736, 3740, 3741, 3747, 3748, 3749, 3750, 3751, + 3752, 3753, 3754, 3758, 3766, 3767, 3771, 3767, 3783, 3784, + 3788, 3788, 3795, 3795, 3809, 3812, 3820, 3828, 3839, 3840, + 3844, 3847, 3854, 3861, 3865, 3873, 3877, 3890, 3893, 3900, + 3900, 3920, 3923, 3929, 3941, 3953, 3956, 3964, 3964, 3979, + 3979, 3997, 3997, 4018, 4021, 4027, 4030, 4036, 4040, 4047, + 4052, 4057, 4064, 4067, 4071, 4075, 4079, 4088, 4092, 4101, + 4104, 4107, 4115, 4115, 4157, 4162, 4165, 4170, 4173, 4178, + 4181, 4186, 4189, 4194, 4197, 4202, 4205, 4210, 4214, 4219, + 4223, 4228, 4232, 4239, 4242, 4247, 4250, 4253, 4256, 4259, + 4264, 4273, 4284, 4289, 4297, 4301, 4306, 4310, 4315, 4319, + 4324, 4328, 4335, 4338, 4343, 4346, 4349, 4352, 4357, 4360, + 4365, 4371, 4374, 4377, 4380, 4385, 4389, 4394, 4398, 4403, + 4407, 4414, 4417, 4422, 4425, 4430, 4433, 4439, 4442, 4447, + 4450 }; #endif @@ -5486,7 +5486,10 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); && (yyvsp[0].interm.intermTypedNode)->getType().containsOpaque()) { TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument((yyvsp[-1].lex).loc, (yyvsp[-2].interm).function, (yyvsp[0].interm.intermTypedNode)); - (yyval.interm).intermNode = parseContext.intermediate.mergeAggregate((yyvsp[-2].interm).intermNode, remappedNode, (yyvsp[-1].lex).loc); + if (remappedNode == (yyvsp[0].interm.intermTypedNode)) + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + else + (yyval.interm).intermNode = parseContext.intermediate.mergeAggregate((yyvsp[-2].interm).intermNode, remappedNode, (yyvsp[-1].lex).loc); (yyval.interm).function = (yyvsp[-2].interm).function; } else @@ -5499,29 +5502,29 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); } } -#line 5503 "MachineIndependent/glslang_tab.cpp" +#line 5506 "MachineIndependent/glslang_tab.cpp" break; case 33: /* function_call_header: function_identifier LEFT_PAREN */ -#line 527 "MachineIndependent/glslang.y" +#line 530 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-1].interm); } -#line 5511 "MachineIndependent/glslang_tab.cpp" +#line 5514 "MachineIndependent/glslang_tab.cpp" break; case 34: /* function_identifier: type_specifier */ -#line 535 "MachineIndependent/glslang.y" +#line 538 "MachineIndependent/glslang.y" { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 5521 "MachineIndependent/glslang_tab.cpp" +#line 5524 "MachineIndependent/glslang_tab.cpp" break; case 35: /* function_identifier: postfix_expression */ -#line 540 "MachineIndependent/glslang.y" +#line 543 "MachineIndependent/glslang.y" { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. @@ -5549,50 +5552,50 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 5553 "MachineIndependent/glslang_tab.cpp" +#line 5556 "MachineIndependent/glslang_tab.cpp" break; case 36: /* function_identifier: non_uniform_qualifier */ -#line 567 "MachineIndependent/glslang.y" +#line 570 "MachineIndependent/glslang.y" { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 5563 "MachineIndependent/glslang_tab.cpp" +#line 5566 "MachineIndependent/glslang_tab.cpp" break; case 37: /* unary_expression: postfix_expression */ -#line 575 "MachineIndependent/glslang.y" +#line 578 "MachineIndependent/glslang.y" { parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); } -#line 5574 "MachineIndependent/glslang_tab.cpp" +#line 5577 "MachineIndependent/glslang_tab.cpp" break; case 38: /* unary_expression: INC_OP unary_expression */ -#line 581 "MachineIndependent/glslang.y" +#line 584 "MachineIndependent/glslang.y" { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); } -#line 5583 "MachineIndependent/glslang_tab.cpp" +#line 5586 "MachineIndependent/glslang_tab.cpp" break; case 39: /* unary_expression: DEC_OP unary_expression */ -#line 585 "MachineIndependent/glslang.y" +#line 588 "MachineIndependent/glslang.y" { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); } -#line 5592 "MachineIndependent/glslang_tab.cpp" +#line 5595 "MachineIndependent/glslang_tab.cpp" break; case 40: /* unary_expression: unary_operator unary_expression */ -#line 589 "MachineIndependent/glslang.y" +#line 592 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; @@ -5609,179 +5612,179 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 5613 "MachineIndependent/glslang_tab.cpp" +#line 5616 "MachineIndependent/glslang_tab.cpp" break; case 41: /* unary_operator: PLUS */ -#line 609 "MachineIndependent/glslang.y" +#line 612 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 5619 "MachineIndependent/glslang_tab.cpp" +#line 5622 "MachineIndependent/glslang_tab.cpp" break; case 42: /* unary_operator: DASH */ -#line 610 "MachineIndependent/glslang.y" +#line 613 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 5625 "MachineIndependent/glslang_tab.cpp" +#line 5628 "MachineIndependent/glslang_tab.cpp" break; case 43: /* unary_operator: BANG */ -#line 611 "MachineIndependent/glslang.y" +#line 614 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 5631 "MachineIndependent/glslang_tab.cpp" +#line 5634 "MachineIndependent/glslang_tab.cpp" break; case 44: /* unary_operator: TILDE */ -#line 612 "MachineIndependent/glslang.y" +#line 615 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } -#line 5638 "MachineIndependent/glslang_tab.cpp" +#line 5641 "MachineIndependent/glslang_tab.cpp" break; case 45: /* multiplicative_expression: unary_expression */ -#line 618 "MachineIndependent/glslang.y" +#line 621 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5644 "MachineIndependent/glslang_tab.cpp" +#line 5647 "MachineIndependent/glslang_tab.cpp" break; case 46: /* multiplicative_expression: multiplicative_expression STAR unary_expression */ -#line 619 "MachineIndependent/glslang.y" +#line 622 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5654 "MachineIndependent/glslang_tab.cpp" +#line 5657 "MachineIndependent/glslang_tab.cpp" break; case 47: /* multiplicative_expression: multiplicative_expression SLASH unary_expression */ -#line 624 "MachineIndependent/glslang.y" +#line 627 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5664 "MachineIndependent/glslang_tab.cpp" +#line 5667 "MachineIndependent/glslang_tab.cpp" break; case 48: /* multiplicative_expression: multiplicative_expression PERCENT unary_expression */ -#line 629 "MachineIndependent/glslang.y" +#line 632 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5675 "MachineIndependent/glslang_tab.cpp" +#line 5678 "MachineIndependent/glslang_tab.cpp" break; case 49: /* additive_expression: multiplicative_expression */ -#line 638 "MachineIndependent/glslang.y" +#line 641 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5681 "MachineIndependent/glslang_tab.cpp" +#line 5684 "MachineIndependent/glslang_tab.cpp" break; case 50: /* additive_expression: additive_expression PLUS multiplicative_expression */ -#line 639 "MachineIndependent/glslang.y" +#line 642 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5691 "MachineIndependent/glslang_tab.cpp" +#line 5694 "MachineIndependent/glslang_tab.cpp" break; case 51: /* additive_expression: additive_expression DASH multiplicative_expression */ -#line 644 "MachineIndependent/glslang.y" +#line 647 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5701 "MachineIndependent/glslang_tab.cpp" +#line 5704 "MachineIndependent/glslang_tab.cpp" break; case 52: /* shift_expression: additive_expression */ -#line 652 "MachineIndependent/glslang.y" +#line 655 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5707 "MachineIndependent/glslang_tab.cpp" +#line 5710 "MachineIndependent/glslang_tab.cpp" break; case 53: /* shift_expression: shift_expression LEFT_OP additive_expression */ -#line 653 "MachineIndependent/glslang.y" +#line 656 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5718 "MachineIndependent/glslang_tab.cpp" +#line 5721 "MachineIndependent/glslang_tab.cpp" break; case 54: /* shift_expression: shift_expression RIGHT_OP additive_expression */ -#line 659 "MachineIndependent/glslang.y" +#line 662 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5729 "MachineIndependent/glslang_tab.cpp" +#line 5732 "MachineIndependent/glslang_tab.cpp" break; case 55: /* relational_expression: shift_expression */ -#line 668 "MachineIndependent/glslang.y" +#line 671 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5735 "MachineIndependent/glslang_tab.cpp" +#line 5738 "MachineIndependent/glslang_tab.cpp" break; case 56: /* relational_expression: relational_expression LEFT_ANGLE shift_expression */ -#line 669 "MachineIndependent/glslang.y" +#line 672 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5745 "MachineIndependent/glslang_tab.cpp" +#line 5748 "MachineIndependent/glslang_tab.cpp" break; case 57: /* relational_expression: relational_expression RIGHT_ANGLE shift_expression */ -#line 674 "MachineIndependent/glslang.y" +#line 677 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5755 "MachineIndependent/glslang_tab.cpp" +#line 5758 "MachineIndependent/glslang_tab.cpp" break; case 58: /* relational_expression: relational_expression LE_OP shift_expression */ -#line 679 "MachineIndependent/glslang.y" +#line 682 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5765 "MachineIndependent/glslang_tab.cpp" +#line 5768 "MachineIndependent/glslang_tab.cpp" break; case 59: /* relational_expression: relational_expression GE_OP shift_expression */ -#line 684 "MachineIndependent/glslang.y" +#line 687 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5775 "MachineIndependent/glslang_tab.cpp" +#line 5778 "MachineIndependent/glslang_tab.cpp" break; case 60: /* equality_expression: relational_expression */ -#line 692 "MachineIndependent/glslang.y" +#line 695 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5781 "MachineIndependent/glslang_tab.cpp" +#line 5784 "MachineIndependent/glslang_tab.cpp" break; case 61: /* equality_expression: equality_expression EQ_OP relational_expression */ -#line 693 "MachineIndependent/glslang.y" +#line 696 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); @@ -5791,11 +5794,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5795 "MachineIndependent/glslang_tab.cpp" +#line 5798 "MachineIndependent/glslang_tab.cpp" break; case 62: /* equality_expression: equality_expression NE_OP relational_expression */ -#line 702 "MachineIndependent/glslang.y" +#line 705 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); @@ -5805,124 +5808,124 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5809 "MachineIndependent/glslang_tab.cpp" +#line 5812 "MachineIndependent/glslang_tab.cpp" break; case 63: /* and_expression: equality_expression */ -#line 714 "MachineIndependent/glslang.y" +#line 717 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5815 "MachineIndependent/glslang_tab.cpp" +#line 5818 "MachineIndependent/glslang_tab.cpp" break; case 64: /* and_expression: and_expression AMPERSAND equality_expression */ -#line 715 "MachineIndependent/glslang.y" +#line 718 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5826 "MachineIndependent/glslang_tab.cpp" +#line 5829 "MachineIndependent/glslang_tab.cpp" break; case 65: /* exclusive_or_expression: and_expression */ -#line 724 "MachineIndependent/glslang.y" +#line 727 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5832 "MachineIndependent/glslang_tab.cpp" +#line 5835 "MachineIndependent/glslang_tab.cpp" break; case 66: /* exclusive_or_expression: exclusive_or_expression CARET and_expression */ -#line 725 "MachineIndependent/glslang.y" +#line 728 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5843 "MachineIndependent/glslang_tab.cpp" +#line 5846 "MachineIndependent/glslang_tab.cpp" break; case 67: /* inclusive_or_expression: exclusive_or_expression */ -#line 734 "MachineIndependent/glslang.y" +#line 737 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5849 "MachineIndependent/glslang_tab.cpp" +#line 5852 "MachineIndependent/glslang_tab.cpp" break; case 68: /* inclusive_or_expression: inclusive_or_expression VERTICAL_BAR exclusive_or_expression */ -#line 735 "MachineIndependent/glslang.y" +#line 738 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5860 "MachineIndependent/glslang_tab.cpp" +#line 5863 "MachineIndependent/glslang_tab.cpp" break; case 69: /* logical_and_expression: inclusive_or_expression */ -#line 744 "MachineIndependent/glslang.y" +#line 747 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5866 "MachineIndependent/glslang_tab.cpp" +#line 5869 "MachineIndependent/glslang_tab.cpp" break; case 70: /* logical_and_expression: logical_and_expression AND_OP inclusive_or_expression */ -#line 745 "MachineIndependent/glslang.y" +#line 748 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5876 "MachineIndependent/glslang_tab.cpp" +#line 5879 "MachineIndependent/glslang_tab.cpp" break; case 71: /* logical_xor_expression: logical_and_expression */ -#line 753 "MachineIndependent/glslang.y" +#line 756 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5882 "MachineIndependent/glslang_tab.cpp" +#line 5885 "MachineIndependent/glslang_tab.cpp" break; case 72: /* logical_xor_expression: logical_xor_expression XOR_OP logical_and_expression */ -#line 754 "MachineIndependent/glslang.y" +#line 757 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5892 "MachineIndependent/glslang_tab.cpp" +#line 5895 "MachineIndependent/glslang_tab.cpp" break; case 73: /* logical_or_expression: logical_xor_expression */ -#line 762 "MachineIndependent/glslang.y" +#line 765 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5898 "MachineIndependent/glslang_tab.cpp" +#line 5901 "MachineIndependent/glslang_tab.cpp" break; case 74: /* logical_or_expression: logical_or_expression OR_OP logical_xor_expression */ -#line 763 "MachineIndependent/glslang.y" +#line 766 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5908 "MachineIndependent/glslang_tab.cpp" +#line 5911 "MachineIndependent/glslang_tab.cpp" break; case 75: /* conditional_expression: logical_or_expression */ -#line 771 "MachineIndependent/glslang.y" +#line 774 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5914 "MachineIndependent/glslang_tab.cpp" +#line 5917 "MachineIndependent/glslang_tab.cpp" break; case 76: /* $@1: %empty */ -#line 772 "MachineIndependent/glslang.y" +#line 775 "MachineIndependent/glslang.y" { ++parseContext.controlFlowNestingLevel; } -#line 5922 "MachineIndependent/glslang_tab.cpp" +#line 5925 "MachineIndependent/glslang_tab.cpp" break; case 77: /* conditional_expression: logical_or_expression QUESTION $@1 expression COLON assignment_expression */ -#line 775 "MachineIndependent/glslang.y" +#line 778 "MachineIndependent/glslang.y" { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); @@ -5935,17 +5938,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 5939 "MachineIndependent/glslang_tab.cpp" +#line 5942 "MachineIndependent/glslang_tab.cpp" break; case 78: /* assignment_expression: conditional_expression */ -#line 790 "MachineIndependent/glslang.y" +#line 793 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5945 "MachineIndependent/glslang_tab.cpp" +#line 5948 "MachineIndependent/glslang_tab.cpp" break; case 79: /* assignment_expression: unary_expression assignment_operator assignment_expression */ -#line 791 "MachineIndependent/glslang.y" +#line 794 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); @@ -5959,119 +5962,119 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } -#line 5963 "MachineIndependent/glslang_tab.cpp" +#line 5966 "MachineIndependent/glslang_tab.cpp" break; case 80: /* assignment_operator: EQUAL */ -#line 807 "MachineIndependent/glslang.y" +#line 810 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 5972 "MachineIndependent/glslang_tab.cpp" +#line 5975 "MachineIndependent/glslang_tab.cpp" break; case 81: /* assignment_operator: MUL_ASSIGN */ -#line 811 "MachineIndependent/glslang.y" +#line 814 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 5981 "MachineIndependent/glslang_tab.cpp" +#line 5984 "MachineIndependent/glslang_tab.cpp" break; case 82: /* assignment_operator: DIV_ASSIGN */ -#line 815 "MachineIndependent/glslang.y" +#line 818 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 5990 "MachineIndependent/glslang_tab.cpp" +#line 5993 "MachineIndependent/glslang_tab.cpp" break; case 83: /* assignment_operator: MOD_ASSIGN */ -#line 819 "MachineIndependent/glslang.y" +#line 822 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpModAssign; } -#line 6000 "MachineIndependent/glslang_tab.cpp" +#line 6003 "MachineIndependent/glslang_tab.cpp" break; case 84: /* assignment_operator: ADD_ASSIGN */ -#line 824 "MachineIndependent/glslang.y" +#line 827 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 6009 "MachineIndependent/glslang_tab.cpp" +#line 6012 "MachineIndependent/glslang_tab.cpp" break; case 85: /* assignment_operator: SUB_ASSIGN */ -#line 828 "MachineIndependent/glslang.y" +#line 831 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 6018 "MachineIndependent/glslang_tab.cpp" +#line 6021 "MachineIndependent/glslang_tab.cpp" break; case 86: /* assignment_operator: LEFT_ASSIGN */ -#line 832 "MachineIndependent/glslang.y" +#line 835 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; } -#line 6027 "MachineIndependent/glslang_tab.cpp" +#line 6030 "MachineIndependent/glslang_tab.cpp" break; case 87: /* assignment_operator: RIGHT_ASSIGN */ -#line 836 "MachineIndependent/glslang.y" +#line 839 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; } -#line 6036 "MachineIndependent/glslang_tab.cpp" +#line 6039 "MachineIndependent/glslang_tab.cpp" break; case 88: /* assignment_operator: AND_ASSIGN */ -#line 840 "MachineIndependent/glslang.y" +#line 843 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; } -#line 6045 "MachineIndependent/glslang_tab.cpp" +#line 6048 "MachineIndependent/glslang_tab.cpp" break; case 89: /* assignment_operator: XOR_ASSIGN */ -#line 844 "MachineIndependent/glslang.y" +#line 847 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; } -#line 6054 "MachineIndependent/glslang_tab.cpp" +#line 6057 "MachineIndependent/glslang_tab.cpp" break; case 90: /* assignment_operator: OR_ASSIGN */ -#line 848 "MachineIndependent/glslang.y" +#line 851 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; } -#line 6063 "MachineIndependent/glslang_tab.cpp" +#line 6066 "MachineIndependent/glslang_tab.cpp" break; case 91: /* expression: assignment_expression */ -#line 855 "MachineIndependent/glslang.y" +#line 858 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 6071 "MachineIndependent/glslang_tab.cpp" +#line 6074 "MachineIndependent/glslang_tab.cpp" break; case 92: /* expression: expression COMMA assignment_expression */ -#line 858 "MachineIndependent/glslang.y" +#line 861 "MachineIndependent/glslang.y" { parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); @@ -6080,30 +6083,30 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 6084 "MachineIndependent/glslang_tab.cpp" +#line 6087 "MachineIndependent/glslang_tab.cpp" break; case 93: /* constant_expression: conditional_expression */ -#line 869 "MachineIndependent/glslang.y" +#line 872 "MachineIndependent/glslang.y" { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 6093 "MachineIndependent/glslang_tab.cpp" +#line 6096 "MachineIndependent/glslang_tab.cpp" break; case 94: /* declaration: function_prototype SEMICOLON */ -#line 876 "MachineIndependent/glslang.y" +#line 879 "MachineIndependent/glslang.y" { parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 6103 "MachineIndependent/glslang_tab.cpp" +#line 6106 "MachineIndependent/glslang_tab.cpp" break; case 95: /* declaration: spirv_instruction_qualifier function_prototype SEMICOLON */ -#line 881 "MachineIndependent/glslang.y" +#line 884 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[-1].interm).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier"); (yyvsp[-1].interm).function->setSpirvInstruction(*(yyvsp[-2].interm.spirvInst)); // Attach SPIR-V intruction qualifier @@ -6111,31 +6114,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 6115 "MachineIndependent/glslang_tab.cpp" +#line 6118 "MachineIndependent/glslang_tab.cpp" break; case 96: /* declaration: spirv_execution_mode_qualifier SEMICOLON */ -#line 888 "MachineIndependent/glslang.y" +#line 891 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "SPIR-V execution mode qualifier"); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier"); (yyval.interm.intermNode) = 0; } -#line 6125 "MachineIndependent/glslang_tab.cpp" +#line 6128 "MachineIndependent/glslang_tab.cpp" break; case 97: /* declaration: init_declarator_list SEMICOLON */ -#line 893 "MachineIndependent/glslang.y" +#line 896 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; } -#line 6135 "MachineIndependent/glslang_tab.cpp" +#line 6138 "MachineIndependent/glslang_tab.cpp" break; case 98: /* declaration: PRECISION precision_qualifier type_specifier SEMICOLON */ -#line 898 "MachineIndependent/glslang.y" +#line 901 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope @@ -6143,75 +6146,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); (yyval.interm.intermNode) = 0; } -#line 6147 "MachineIndependent/glslang_tab.cpp" +#line 6150 "MachineIndependent/glslang_tab.cpp" break; case 99: /* declaration: block_structure SEMICOLON */ -#line 905 "MachineIndependent/glslang.y" +#line 908 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 6156 "MachineIndependent/glslang_tab.cpp" +#line 6159 "MachineIndependent/glslang_tab.cpp" break; case 100: /* declaration: block_structure IDENTIFIER SEMICOLON */ -#line 909 "MachineIndependent/glslang.y" +#line 912 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 6165 "MachineIndependent/glslang_tab.cpp" +#line 6168 "MachineIndependent/glslang_tab.cpp" break; case 101: /* declaration: block_structure IDENTIFIER array_specifier SEMICOLON */ -#line 913 "MachineIndependent/glslang.y" +#line 916 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); (yyval.interm.intermNode) = 0; } -#line 6174 "MachineIndependent/glslang_tab.cpp" +#line 6177 "MachineIndependent/glslang_tab.cpp" break; case 102: /* declaration: type_qualifier SEMICOLON */ -#line 917 "MachineIndependent/glslang.y" +#line 920 "MachineIndependent/glslang.y" { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); (yyval.interm.intermNode) = 0; } -#line 6184 "MachineIndependent/glslang_tab.cpp" +#line 6187 "MachineIndependent/glslang_tab.cpp" break; case 103: /* declaration: type_qualifier IDENTIFIER SEMICOLON */ -#line 922 "MachineIndependent/glslang.y" +#line 925 "MachineIndependent/glslang.y" { parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 6194 "MachineIndependent/glslang_tab.cpp" +#line 6197 "MachineIndependent/glslang_tab.cpp" break; case 104: /* declaration: type_qualifier IDENTIFIER identifier_list SEMICOLON */ -#line 927 "MachineIndependent/glslang.y" +#line 930 "MachineIndependent/glslang.y" { parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); (yyval.interm.intermNode) = 0; } -#line 6205 "MachineIndependent/glslang_tab.cpp" +#line 6208 "MachineIndependent/glslang_tab.cpp" break; case 105: /* $@2: %empty */ -#line 936 "MachineIndependent/glslang.y" +#line 939 "MachineIndependent/glslang.y" { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 6211 "MachineIndependent/glslang_tab.cpp" +#line 6214 "MachineIndependent/glslang_tab.cpp" break; case 106: /* block_structure: type_qualifier IDENTIFIER LEFT_BRACE $@2 struct_declaration_list RIGHT_BRACE */ -#line 936 "MachineIndependent/glslang.y" +#line 939 "MachineIndependent/glslang.y" { --parseContext.blockNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; @@ -6221,39 +6224,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 6225 "MachineIndependent/glslang_tab.cpp" +#line 6228 "MachineIndependent/glslang_tab.cpp" break; case 107: /* identifier_list: COMMA IDENTIFIER */ -#line 947 "MachineIndependent/glslang.y" +#line 950 "MachineIndependent/glslang.y" { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 6234 "MachineIndependent/glslang_tab.cpp" +#line 6237 "MachineIndependent/glslang_tab.cpp" break; case 108: /* identifier_list: identifier_list COMMA IDENTIFIER */ -#line 951 "MachineIndependent/glslang.y" +#line 954 "MachineIndependent/glslang.y" { (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 6243 "MachineIndependent/glslang_tab.cpp" +#line 6246 "MachineIndependent/glslang_tab.cpp" break; case 109: /* function_prototype: function_declarator RIGHT_PAREN */ -#line 958 "MachineIndependent/glslang.y" +#line 961 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-1].interm.function); if (parseContext.compileOnly) (yyval.interm).function->setExport(); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 6253 "MachineIndependent/glslang_tab.cpp" +#line 6256 "MachineIndependent/glslang_tab.cpp" break; case 110: /* function_prototype: function_declarator RIGHT_PAREN attribute */ -#line 963 "MachineIndependent/glslang.y" +#line 966 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-2].interm.function); if (parseContext.compileOnly) (yyval.interm).function->setExport(); @@ -6262,11 +6265,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.requireExtensions((yyvsp[-1].lex).loc, 2, extensions, "attribute"); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes)); } -#line 6266 "MachineIndependent/glslang_tab.cpp" +#line 6269 "MachineIndependent/glslang_tab.cpp" break; case 111: /* function_prototype: attribute function_declarator RIGHT_PAREN */ -#line 971 "MachineIndependent/glslang.y" +#line 974 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-1].interm.function); if (parseContext.compileOnly) (yyval.interm).function->setExport(); @@ -6275,11 +6278,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.requireExtensions((yyvsp[0].lex).loc, 2, extensions, "attribute"); parseContext.handleFunctionAttributes((yyvsp[0].lex).loc, *(yyvsp[-2].interm.attributes)); } -#line 6279 "MachineIndependent/glslang_tab.cpp" +#line 6282 "MachineIndependent/glslang_tab.cpp" break; case 112: /* function_prototype: attribute function_declarator RIGHT_PAREN attribute */ -#line 979 "MachineIndependent/glslang.y" +#line 982 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-2].interm.function); if (parseContext.compileOnly) (yyval.interm).function->setExport(); @@ -6289,27 +6292,27 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[-3].interm.attributes)); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes)); } -#line 6293 "MachineIndependent/glslang_tab.cpp" +#line 6296 "MachineIndependent/glslang_tab.cpp" break; case 113: /* function_declarator: function_header */ -#line 991 "MachineIndependent/glslang.y" +#line 994 "MachineIndependent/glslang.y" { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 6301 "MachineIndependent/glslang_tab.cpp" +#line 6304 "MachineIndependent/glslang_tab.cpp" break; case 114: /* function_declarator: function_header_with_parameters */ -#line 994 "MachineIndependent/glslang.y" +#line 997 "MachineIndependent/glslang.y" { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 6309 "MachineIndependent/glslang_tab.cpp" +#line 6312 "MachineIndependent/glslang_tab.cpp" break; case 115: /* function_header_with_parameters: function_header parameter_declaration */ -#line 1001 "MachineIndependent/glslang.y" +#line 1004 "MachineIndependent/glslang.y" { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); @@ -6323,11 +6326,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else delete (yyvsp[0].interm).param.type; } -#line 6327 "MachineIndependent/glslang_tab.cpp" +#line 6330 "MachineIndependent/glslang_tab.cpp" break; case 116: /* function_header_with_parameters: function_header_with_parameters COMMA parameter_declaration */ -#line 1014 "MachineIndependent/glslang.y" +#line 1017 "MachineIndependent/glslang.y" { // // Only first parameter of one-parameter functions can be void @@ -6348,11 +6351,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.vkRelaxedRemapFunctionParameter((yyvsp[-2].interm.function), (yyvsp[0].interm).param); } } -#line 6352 "MachineIndependent/glslang_tab.cpp" +#line 6355 "MachineIndependent/glslang_tab.cpp" break; case 117: /* function_header: fully_specified_type IDENTIFIER LEFT_PAREN */ -#line 1037 "MachineIndependent/glslang.y" +#line 1040 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", @@ -6372,11 +6375,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 6376 "MachineIndependent/glslang_tab.cpp" +#line 6379 "MachineIndependent/glslang_tab.cpp" break; case 118: /* parameter_declarator: type_specifier IDENTIFIER */ -#line 1060 "MachineIndependent/glslang.y" +#line 1063 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -6392,11 +6395,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 6396 "MachineIndependent/glslang_tab.cpp" +#line 6399 "MachineIndependent/glslang_tab.cpp" break; case 119: /* parameter_declarator: type_specifier IDENTIFIER array_specifier */ -#line 1075 "MachineIndependent/glslang.y" +#line 1078 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -6416,11 +6419,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 6420 "MachineIndependent/glslang_tab.cpp" +#line 6423 "MachineIndependent/glslang_tab.cpp" break; case 120: /* parameter_declaration: type_qualifier parameter_declarator */ -#line 1100 "MachineIndependent/glslang.y" +#line 1103 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -6432,11 +6435,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 6436 "MachineIndependent/glslang_tab.cpp" +#line 6439 "MachineIndependent/glslang_tab.cpp" break; case 121: /* parameter_declaration: parameter_declarator */ -#line 1111 "MachineIndependent/glslang.y" +#line 1114 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); @@ -6444,11 +6447,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); } -#line 6448 "MachineIndependent/glslang_tab.cpp" +#line 6451 "MachineIndependent/glslang_tab.cpp" break; case 122: /* parameter_declaration: type_qualifier parameter_type_specifier */ -#line 1121 "MachineIndependent/glslang.y" +#line 1124 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) @@ -6459,11 +6462,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 6463 "MachineIndependent/glslang_tab.cpp" +#line 6466 "MachineIndependent/glslang_tab.cpp" break; case 123: /* parameter_declaration: parameter_type_specifier */ -#line 1131 "MachineIndependent/glslang.y" +#line 1134 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); @@ -6471,118 +6474,118 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); } -#line 6475 "MachineIndependent/glslang_tab.cpp" +#line 6478 "MachineIndependent/glslang_tab.cpp" break; case 124: /* parameter_type_specifier: type_specifier */ -#line 1141 "MachineIndependent/glslang.y" +#line 1144 "MachineIndependent/glslang.y" { TParameter param = { 0, new TType((yyvsp[0].interm.type)), {} }; (yyval.interm).param = param; if ((yyvsp[0].interm.type).arraySizes) parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); } -#line 6486 "MachineIndependent/glslang_tab.cpp" +#line 6489 "MachineIndependent/glslang_tab.cpp" break; case 125: /* init_declarator_list: single_declaration */ -#line 1150 "MachineIndependent/glslang.y" +#line 1153 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); } -#line 6494 "MachineIndependent/glslang_tab.cpp" +#line 6497 "MachineIndependent/glslang_tab.cpp" break; case 126: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER */ -#line 1153 "MachineIndependent/glslang.y" +#line 1156 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-2].interm); parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); } -#line 6503 "MachineIndependent/glslang_tab.cpp" +#line 6506 "MachineIndependent/glslang_tab.cpp" break; case 127: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier */ -#line 1157 "MachineIndependent/glslang.y" +#line 1160 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-3].interm); parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); } -#line 6512 "MachineIndependent/glslang_tab.cpp" +#line 6515 "MachineIndependent/glslang_tab.cpp" break; case 128: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer */ -#line 1161 "MachineIndependent/glslang.y" +#line 1164 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-5].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 6522 "MachineIndependent/glslang_tab.cpp" +#line 6525 "MachineIndependent/glslang_tab.cpp" break; case 129: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER EQUAL initializer */ -#line 1166 "MachineIndependent/glslang.y" +#line 1169 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-4].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 6532 "MachineIndependent/glslang_tab.cpp" +#line 6535 "MachineIndependent/glslang_tab.cpp" break; case 130: /* single_declaration: fully_specified_type */ -#line 1174 "MachineIndependent/glslang.y" +#line 1177 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[0].interm.type); (yyval.interm).intermNode = 0; parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); } -#line 6542 "MachineIndependent/glslang_tab.cpp" +#line 6545 "MachineIndependent/glslang_tab.cpp" break; case 131: /* single_declaration: fully_specified_type IDENTIFIER */ -#line 1179 "MachineIndependent/glslang.y" +#line 1182 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-1].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); } -#line 6552 "MachineIndependent/glslang_tab.cpp" +#line 6555 "MachineIndependent/glslang_tab.cpp" break; case 132: /* single_declaration: fully_specified_type IDENTIFIER array_specifier */ -#line 1184 "MachineIndependent/glslang.y" +#line 1187 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-2].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); } -#line 6562 "MachineIndependent/glslang_tab.cpp" +#line 6565 "MachineIndependent/glslang_tab.cpp" break; case 133: /* single_declaration: fully_specified_type IDENTIFIER array_specifier EQUAL initializer */ -#line 1189 "MachineIndependent/glslang.y" +#line 1192 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-4].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 6572 "MachineIndependent/glslang_tab.cpp" +#line 6575 "MachineIndependent/glslang_tab.cpp" break; case 134: /* single_declaration: fully_specified_type IDENTIFIER EQUAL initializer */ -#line 1194 "MachineIndependent/glslang.y" +#line 1197 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-3].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 6582 "MachineIndependent/glslang_tab.cpp" +#line 6585 "MachineIndependent/glslang_tab.cpp" break; case 135: /* fully_specified_type: type_specifier */ -#line 1203 "MachineIndependent/glslang.y" +#line 1206 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -6593,11 +6596,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier, (yyval.interm.type).isCoopmat()); } -#line 6597 "MachineIndependent/glslang_tab.cpp" +#line 6600 "MachineIndependent/glslang_tab.cpp" break; case 136: /* fully_specified_type: type_qualifier type_specifier */ -#line 1213 "MachineIndependent/glslang.y" +#line 1216 "MachineIndependent/glslang.y" { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, false, &(yyvsp[0].interm.type)); parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); @@ -6622,22 +6625,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 6626 "MachineIndependent/glslang_tab.cpp" +#line 6629 "MachineIndependent/glslang_tab.cpp" break; case 137: /* invariant_qualifier: INVARIANT */ -#line 1240 "MachineIndependent/glslang.y" +#line 1243 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.invariant = true; } -#line 6637 "MachineIndependent/glslang_tab.cpp" +#line 6640 "MachineIndependent/glslang_tab.cpp" break; case 138: /* interpolation_qualifier: SMOOTH */ -#line 1249 "MachineIndependent/glslang.y" +#line 1252 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); @@ -6645,11 +6648,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 6649 "MachineIndependent/glslang_tab.cpp" +#line 6652 "MachineIndependent/glslang_tab.cpp" break; case 139: /* interpolation_qualifier: FLAT */ -#line 1256 "MachineIndependent/glslang.y" +#line 1259 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); @@ -6657,11 +6660,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 6661 "MachineIndependent/glslang_tab.cpp" +#line 6664 "MachineIndependent/glslang_tab.cpp" break; case 140: /* interpolation_qualifier: NOPERSPECTIVE */ -#line 1263 "MachineIndependent/glslang.y" +#line 1266 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); @@ -6669,11 +6672,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nopersp = true; } -#line 6673 "MachineIndependent/glslang_tab.cpp" +#line 6676 "MachineIndependent/glslang_tab.cpp" break; case 141: /* interpolation_qualifier: EXPLICITINTERPAMD */ -#line 1270 "MachineIndependent/glslang.y" +#line 1273 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); @@ -6681,11 +6684,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.explicitInterp = true; } -#line 6685 "MachineIndependent/glslang_tab.cpp" +#line 6688 "MachineIndependent/glslang_tab.cpp" break; case 142: /* interpolation_qualifier: PERVERTEXNV */ -#line 1277 "MachineIndependent/glslang.y" +#line 1280 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); @@ -6694,11 +6697,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexNV = true; } -#line 6698 "MachineIndependent/glslang_tab.cpp" +#line 6701 "MachineIndependent/glslang_tab.cpp" break; case 143: /* interpolation_qualifier: PERVERTEXEXT */ -#line 1285 "MachineIndependent/glslang.y" +#line 1288 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexEXT"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric"); @@ -6707,11 +6710,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexEXT = true; } -#line 6711 "MachineIndependent/glslang_tab.cpp" +#line 6714 "MachineIndependent/glslang_tab.cpp" break; case 144: /* interpolation_qualifier: PERPRIMITIVENV */ -#line 1293 "MachineIndependent/glslang.y" +#line 1296 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); @@ -6722,11 +6725,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; } -#line 6726 "MachineIndependent/glslang_tab.cpp" +#line 6729 "MachineIndependent/glslang_tab.cpp" break; case 145: /* interpolation_qualifier: PERPRIMITIVEEXT */ -#line 1303 "MachineIndependent/glslang.y" +#line 1306 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveEXT"); @@ -6737,11 +6740,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; } -#line 6741 "MachineIndependent/glslang_tab.cpp" +#line 6744 "MachineIndependent/glslang_tab.cpp" break; case 146: /* interpolation_qualifier: PERVIEWNV */ -#line 1313 "MachineIndependent/glslang.y" +#line 1316 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); @@ -6749,11 +6752,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; } -#line 6753 "MachineIndependent/glslang_tab.cpp" +#line 6756 "MachineIndependent/glslang_tab.cpp" break; case 147: /* interpolation_qualifier: PERTASKNV */ -#line 1320 "MachineIndependent/glslang.y" +#line 1323 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); @@ -6761,84 +6764,84 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; } -#line 6765 "MachineIndependent/glslang_tab.cpp" +#line 6768 "MachineIndependent/glslang_tab.cpp" break; case 148: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */ -#line 1330 "MachineIndependent/glslang.y" +#line 1333 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 6773 "MachineIndependent/glslang_tab.cpp" +#line 6776 "MachineIndependent/glslang_tab.cpp" break; case 149: /* layout_qualifier_id_list: layout_qualifier_id */ -#line 1336 "MachineIndependent/glslang.y" +#line 1339 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6781 "MachineIndependent/glslang_tab.cpp" +#line 6784 "MachineIndependent/glslang_tab.cpp" break; case 150: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */ -#line 1339 "MachineIndependent/glslang.y" +#line 1342 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-2].interm.type); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 6791 "MachineIndependent/glslang_tab.cpp" +#line 6794 "MachineIndependent/glslang_tab.cpp" break; case 151: /* layout_qualifier_id: IDENTIFIER */ -#line 1346 "MachineIndependent/glslang.y" +#line 1349 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); } -#line 6800 "MachineIndependent/glslang_tab.cpp" +#line 6803 "MachineIndependent/glslang_tab.cpp" break; case 152: /* layout_qualifier_id: IDENTIFIER EQUAL constant_expression */ -#line 1350 "MachineIndependent/glslang.y" +#line 1353 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-2].lex).loc); parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); } -#line 6809 "MachineIndependent/glslang_tab.cpp" +#line 6812 "MachineIndependent/glslang_tab.cpp" break; case 153: /* layout_qualifier_id: SHARED */ -#line 1354 "MachineIndependent/glslang.y" +#line 1357 "MachineIndependent/glslang.y" { // because "shared" is both an identifier and a keyword (yyval.interm.type).init((yyvsp[0].lex).loc); TString strShared("shared"); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); } -#line 6819 "MachineIndependent/glslang_tab.cpp" +#line 6822 "MachineIndependent/glslang_tab.cpp" break; case 154: /* precise_qualifier: PRECISE */ -#line 1362 "MachineIndependent/glslang.y" +#line 1365 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.noContraction = true; } -#line 6830 "MachineIndependent/glslang_tab.cpp" +#line 6833 "MachineIndependent/glslang_tab.cpp" break; case 155: /* type_qualifier: single_type_qualifier */ -#line 1371 "MachineIndependent/glslang.y" +#line 1374 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6838 "MachineIndependent/glslang_tab.cpp" +#line 6841 "MachineIndependent/glslang_tab.cpp" break; case 156: /* type_qualifier: type_qualifier single_type_qualifier */ -#line 1374 "MachineIndependent/glslang.y" +#line 1377 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) @@ -6847,151 +6850,151 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 6851 "MachineIndependent/glslang_tab.cpp" +#line 6854 "MachineIndependent/glslang_tab.cpp" break; case 157: /* single_type_qualifier: storage_qualifier */ -#line 1385 "MachineIndependent/glslang.y" +#line 1388 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6859 "MachineIndependent/glslang_tab.cpp" +#line 6862 "MachineIndependent/glslang_tab.cpp" break; case 158: /* single_type_qualifier: layout_qualifier */ -#line 1388 "MachineIndependent/glslang.y" +#line 1391 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6867 "MachineIndependent/glslang_tab.cpp" +#line 6870 "MachineIndependent/glslang_tab.cpp" break; case 159: /* single_type_qualifier: precision_qualifier */ -#line 1391 "MachineIndependent/glslang.y" +#line 1394 "MachineIndependent/glslang.y" { parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6876 "MachineIndependent/glslang_tab.cpp" +#line 6879 "MachineIndependent/glslang_tab.cpp" break; case 160: /* single_type_qualifier: interpolation_qualifier */ -#line 1395 "MachineIndependent/glslang.y" +#line 1398 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6885 "MachineIndependent/glslang_tab.cpp" +#line 6888 "MachineIndependent/glslang_tab.cpp" break; case 161: /* single_type_qualifier: invariant_qualifier */ -#line 1399 "MachineIndependent/glslang.y" +#line 1402 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6894 "MachineIndependent/glslang_tab.cpp" +#line 6897 "MachineIndependent/glslang_tab.cpp" break; case 162: /* single_type_qualifier: precise_qualifier */ -#line 1403 "MachineIndependent/glslang.y" +#line 1406 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6903 "MachineIndependent/glslang_tab.cpp" +#line 6906 "MachineIndependent/glslang_tab.cpp" break; case 163: /* single_type_qualifier: non_uniform_qualifier */ -#line 1407 "MachineIndependent/glslang.y" +#line 1410 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6911 "MachineIndependent/glslang_tab.cpp" +#line 6914 "MachineIndependent/glslang_tab.cpp" break; case 164: /* single_type_qualifier: spirv_storage_class_qualifier */ -#line 1410 "MachineIndependent/glslang.y" +#line 1413 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].interm.type).loc, "spirv_storage_class"); parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6921 "MachineIndependent/glslang_tab.cpp" +#line 6924 "MachineIndependent/glslang_tab.cpp" break; case 165: /* single_type_qualifier: spirv_decorate_qualifier */ -#line 1415 "MachineIndependent/glslang.y" +#line 1418 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6930 "MachineIndependent/glslang_tab.cpp" +#line 6933 "MachineIndependent/glslang_tab.cpp" break; case 166: /* single_type_qualifier: SPIRV_BY_REFERENCE */ -#line 1419 "MachineIndependent/glslang.y" +#line 1422 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.setSpirvByReference(); } -#line 6940 "MachineIndependent/glslang_tab.cpp" +#line 6943 "MachineIndependent/glslang_tab.cpp" break; case 167: /* single_type_qualifier: SPIRV_LITERAL */ -#line 1424 "MachineIndependent/glslang.y" +#line 1427 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.setSpirvLiteral(); } -#line 6950 "MachineIndependent/glslang_tab.cpp" +#line 6953 "MachineIndependent/glslang_tab.cpp" break; case 168: /* storage_qualifier: CONST */ -#line 1432 "MachineIndependent/glslang.y" +#line 1435 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } -#line 6959 "MachineIndependent/glslang_tab.cpp" +#line 6962 "MachineIndependent/glslang_tab.cpp" break; case 169: /* storage_qualifier: INOUT */ -#line 1436 "MachineIndependent/glslang.y" +#line 1439 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqInOut; } -#line 6969 "MachineIndependent/glslang_tab.cpp" +#line 6972 "MachineIndependent/glslang_tab.cpp" break; case 170: /* storage_qualifier: IN */ -#line 1441 "MachineIndependent/glslang.y" +#line 1444 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "in"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqIn; } -#line 6980 "MachineIndependent/glslang_tab.cpp" +#line 6983 "MachineIndependent/glslang_tab.cpp" break; case 171: /* storage_qualifier: OUT */ -#line 1447 "MachineIndependent/glslang.y" +#line 1450 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "out"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqOut; } -#line 6991 "MachineIndependent/glslang_tab.cpp" +#line 6994 "MachineIndependent/glslang_tab.cpp" break; case 172: /* storage_qualifier: CENTROID */ -#line 1453 "MachineIndependent/glslang.y" +#line 1456 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); @@ -6999,31 +7002,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.centroid = true; } -#line 7003 "MachineIndependent/glslang_tab.cpp" +#line 7006 "MachineIndependent/glslang_tab.cpp" break; case 173: /* storage_qualifier: UNIFORM */ -#line 1460 "MachineIndependent/glslang.y" +#line 1463 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqUniform; } -#line 7013 "MachineIndependent/glslang_tab.cpp" +#line 7016 "MachineIndependent/glslang_tab.cpp" break; case 174: /* storage_qualifier: TILEIMAGEEXT */ -#line 1465 "MachineIndependent/glslang.y" +#line 1468 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "tileImageEXT"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqTileImageEXT; } -#line 7023 "MachineIndependent/glslang_tab.cpp" +#line 7026 "MachineIndependent/glslang_tab.cpp" break; case 175: /* storage_qualifier: SHARED */ -#line 1470 "MachineIndependent/glslang.y" +#line 1473 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); @@ -7032,21 +7035,21 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqShared; } -#line 7036 "MachineIndependent/glslang_tab.cpp" +#line 7039 "MachineIndependent/glslang_tab.cpp" break; case 176: /* storage_qualifier: BUFFER */ -#line 1478 "MachineIndependent/glslang.y" +#line 1481 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqBuffer; } -#line 7046 "MachineIndependent/glslang_tab.cpp" +#line 7049 "MachineIndependent/glslang_tab.cpp" break; case 177: /* storage_qualifier: ATTRIBUTE */ -#line 1483 "MachineIndependent/glslang.y" +#line 1486 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); @@ -7059,11 +7062,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 7063 "MachineIndependent/glslang_tab.cpp" +#line 7066 "MachineIndependent/glslang_tab.cpp" break; case 178: /* storage_qualifier: VARYING */ -#line 1495 "MachineIndependent/glslang.y" +#line 1498 "MachineIndependent/glslang.y" { parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); @@ -7078,32 +7081,32 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 7082 "MachineIndependent/glslang_tab.cpp" +#line 7085 "MachineIndependent/glslang_tab.cpp" break; case 179: /* storage_qualifier: PATCH */ -#line 1509 "MachineIndependent/glslang.y" +#line 1512 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.patch = true; } -#line 7093 "MachineIndependent/glslang_tab.cpp" +#line 7096 "MachineIndependent/glslang_tab.cpp" break; case 180: /* storage_qualifier: SAMPLE */ -#line 1515 "MachineIndependent/glslang.y" +#line 1518 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.sample = true; } -#line 7103 "MachineIndependent/glslang_tab.cpp" +#line 7106 "MachineIndependent/glslang_tab.cpp" break; case 181: /* storage_qualifier: HITATTRNV */ -#line 1520 "MachineIndependent/glslang.y" +#line 1523 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask @@ -7112,11 +7115,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 7116 "MachineIndependent/glslang_tab.cpp" +#line 7119 "MachineIndependent/glslang_tab.cpp" break; case 182: /* storage_qualifier: HITOBJECTATTRNV */ -#line 1528 "MachineIndependent/glslang.y" +#line 1531 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask @@ -7125,11 +7128,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitObjectAttrNV; } -#line 7129 "MachineIndependent/glslang_tab.cpp" +#line 7132 "MachineIndependent/glslang_tab.cpp" break; case 183: /* storage_qualifier: HITATTREXT */ -#line 1536 "MachineIndependent/glslang.y" +#line 1539 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask @@ -7138,11 +7141,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 7142 "MachineIndependent/glslang_tab.cpp" +#line 7145 "MachineIndependent/glslang_tab.cpp" break; case 184: /* storage_qualifier: PAYLOADNV */ -#line 1544 "MachineIndependent/glslang.y" +#line 1547 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -7151,11 +7154,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 7155 "MachineIndependent/glslang_tab.cpp" +#line 7158 "MachineIndependent/glslang_tab.cpp" break; case 185: /* storage_qualifier: PAYLOADEXT */ -#line 1552 "MachineIndependent/glslang.y" +#line 1555 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -7164,11 +7167,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 7168 "MachineIndependent/glslang_tab.cpp" +#line 7171 "MachineIndependent/glslang_tab.cpp" break; case 186: /* storage_qualifier: PAYLOADINNV */ -#line 1560 "MachineIndependent/glslang.y" +#line 1563 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | @@ -7177,11 +7180,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 7181 "MachineIndependent/glslang_tab.cpp" +#line 7184 "MachineIndependent/glslang_tab.cpp" break; case 187: /* storage_qualifier: PAYLOADINEXT */ -#line 1568 "MachineIndependent/glslang.y" +#line 1571 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | @@ -7190,11 +7193,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 7194 "MachineIndependent/glslang_tab.cpp" +#line 7197 "MachineIndependent/glslang_tab.cpp" break; case 188: /* storage_qualifier: CALLDATANV */ -#line 1576 "MachineIndependent/glslang.y" +#line 1579 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -7203,11 +7206,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 7207 "MachineIndependent/glslang_tab.cpp" +#line 7210 "MachineIndependent/glslang_tab.cpp" break; case 189: /* storage_qualifier: CALLDATAEXT */ -#line 1584 "MachineIndependent/glslang.y" +#line 1587 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -7216,11 +7219,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 7220 "MachineIndependent/glslang_tab.cpp" +#line 7223 "MachineIndependent/glslang_tab.cpp" break; case 190: /* storage_qualifier: CALLDATAINNV */ -#line 1592 "MachineIndependent/glslang.y" +#line 1595 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); @@ -7228,11 +7231,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 7232 "MachineIndependent/glslang_tab.cpp" +#line 7235 "MachineIndependent/glslang_tab.cpp" break; case 191: /* storage_qualifier: CALLDATAINEXT */ -#line 1599 "MachineIndependent/glslang.y" +#line 1602 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); @@ -7240,138 +7243,138 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 7244 "MachineIndependent/glslang_tab.cpp" +#line 7247 "MachineIndependent/glslang_tab.cpp" break; case 192: /* storage_qualifier: COHERENT */ -#line 1606 "MachineIndependent/glslang.y" +#line 1609 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 7253 "MachineIndependent/glslang_tab.cpp" +#line 7256 "MachineIndependent/glslang_tab.cpp" break; case 193: /* storage_qualifier: DEVICECOHERENT */ -#line 1610 "MachineIndependent/glslang.y" +#line 1613 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); (yyval.interm.type).qualifier.devicecoherent = true; } -#line 7263 "MachineIndependent/glslang_tab.cpp" +#line 7266 "MachineIndependent/glslang_tab.cpp" break; case 194: /* storage_qualifier: QUEUEFAMILYCOHERENT */ -#line 1615 "MachineIndependent/glslang.y" +#line 1618 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); (yyval.interm.type).qualifier.queuefamilycoherent = true; } -#line 7273 "MachineIndependent/glslang_tab.cpp" +#line 7276 "MachineIndependent/glslang_tab.cpp" break; case 195: /* storage_qualifier: WORKGROUPCOHERENT */ -#line 1620 "MachineIndependent/glslang.y" +#line 1623 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); (yyval.interm.type).qualifier.workgroupcoherent = true; } -#line 7283 "MachineIndependent/glslang_tab.cpp" +#line 7286 "MachineIndependent/glslang_tab.cpp" break; case 196: /* storage_qualifier: SUBGROUPCOHERENT */ -#line 1625 "MachineIndependent/glslang.y" +#line 1628 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); (yyval.interm.type).qualifier.subgroupcoherent = true; } -#line 7293 "MachineIndependent/glslang_tab.cpp" +#line 7296 "MachineIndependent/glslang_tab.cpp" break; case 197: /* storage_qualifier: NONPRIVATE */ -#line 1630 "MachineIndependent/glslang.y" +#line 1633 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); (yyval.interm.type).qualifier.nonprivate = true; } -#line 7303 "MachineIndependent/glslang_tab.cpp" +#line 7306 "MachineIndependent/glslang_tab.cpp" break; case 198: /* storage_qualifier: SHADERCALLCOHERENT */ -#line 1635 "MachineIndependent/glslang.y" +#line 1638 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); (yyval.interm.type).qualifier.shadercallcoherent = true; } -#line 7313 "MachineIndependent/glslang_tab.cpp" +#line 7316 "MachineIndependent/glslang_tab.cpp" break; case 199: /* storage_qualifier: VOLATILE */ -#line 1640 "MachineIndependent/glslang.y" +#line 1643 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 7322 "MachineIndependent/glslang_tab.cpp" +#line 7325 "MachineIndependent/glslang_tab.cpp" break; case 200: /* storage_qualifier: RESTRICT */ -#line 1644 "MachineIndependent/glslang.y" +#line 1647 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 7331 "MachineIndependent/glslang_tab.cpp" +#line 7334 "MachineIndependent/glslang_tab.cpp" break; case 201: /* storage_qualifier: READONLY */ -#line 1648 "MachineIndependent/glslang.y" +#line 1651 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 7340 "MachineIndependent/glslang_tab.cpp" +#line 7343 "MachineIndependent/glslang_tab.cpp" break; case 202: /* storage_qualifier: WRITEONLY */ -#line 1652 "MachineIndependent/glslang.y" +#line 1655 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 7349 "MachineIndependent/glslang_tab.cpp" +#line 7352 "MachineIndependent/glslang_tab.cpp" break; case 203: /* storage_qualifier: SUBROUTINE */ -#line 1656 "MachineIndependent/glslang.y" +#line 1659 "MachineIndependent/glslang.y" { parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[0].lex).loc); } -#line 7360 "MachineIndependent/glslang_tab.cpp" +#line 7363 "MachineIndependent/glslang_tab.cpp" break; case 204: /* storage_qualifier: SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN */ -#line 1662 "MachineIndependent/glslang.y" +#line 1665 "MachineIndependent/glslang.y" { parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[-3].lex).loc); } -#line 7371 "MachineIndependent/glslang_tab.cpp" +#line 7374 "MachineIndependent/glslang_tab.cpp" break; case 205: /* storage_qualifier: TASKPAYLOADWORKGROUPEXT */ -#line 1668 "MachineIndependent/glslang.y" +#line 1671 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskPayloadSharedEXT"); @@ -7379,38 +7382,38 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqtaskPayloadSharedEXT; } -#line 7383 "MachineIndependent/glslang_tab.cpp" +#line 7386 "MachineIndependent/glslang_tab.cpp" break; case 206: /* non_uniform_qualifier: NONUNIFORM */ -#line 1678 "MachineIndependent/glslang.y" +#line 1681 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 7392 "MachineIndependent/glslang_tab.cpp" +#line 7395 "MachineIndependent/glslang_tab.cpp" break; case 207: /* type_name_list: IDENTIFIER */ -#line 1685 "MachineIndependent/glslang.y" +#line 1688 "MachineIndependent/glslang.y" { // TODO } -#line 7400 "MachineIndependent/glslang_tab.cpp" +#line 7403 "MachineIndependent/glslang_tab.cpp" break; case 208: /* type_name_list: type_name_list COMMA IDENTIFIER */ -#line 1688 "MachineIndependent/glslang.y" +#line 1691 "MachineIndependent/glslang.y" { // TODO: 4.0 semantics: subroutines // 1) make sure each identifier is a type declared earlier with SUBROUTINE // 2) save all of the identifiers for future comparison with the declared function } -#line 7410 "MachineIndependent/glslang_tab.cpp" +#line 7413 "MachineIndependent/glslang_tab.cpp" break; case 209: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt */ -#line 1696 "MachineIndependent/glslang.y" +#line 1699 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); @@ -7418,11 +7421,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.coopMatTypeParametersCheck((yyvsp[-1].interm.type).loc, (yyval.interm.type)); } -#line 7422 "MachineIndependent/glslang_tab.cpp" +#line 7425 "MachineIndependent/glslang_tab.cpp" break; case 210: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt array_specifier */ -#line 1703 "MachineIndependent/glslang.y" +#line 1706 "MachineIndependent/glslang.y" { parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); (yyval.interm.type) = (yyvsp[-2].interm.type); @@ -7431,21 +7434,21 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; parseContext.coopMatTypeParametersCheck((yyvsp[-2].interm.type).loc, (yyval.interm.type)); } -#line 7435 "MachineIndependent/glslang_tab.cpp" +#line 7438 "MachineIndependent/glslang_tab.cpp" break; case 211: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */ -#line 1714 "MachineIndependent/glslang.y" +#line 1717 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).arraySizes = new TArraySizes; (yyval.interm).arraySizes->addInnerSize(); } -#line 7445 "MachineIndependent/glslang_tab.cpp" +#line 7448 "MachineIndependent/glslang_tab.cpp" break; case 212: /* array_specifier: LEFT_BRACKET conditional_expression RIGHT_BRACKET */ -#line 1719 "MachineIndependent/glslang.y" +#line 1722 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[-2].lex).loc; (yyval.interm).arraySizes = new TArraySizes; @@ -7454,20 +7457,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 7458 "MachineIndependent/glslang_tab.cpp" +#line 7461 "MachineIndependent/glslang_tab.cpp" break; case 213: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */ -#line 1727 "MachineIndependent/glslang.y" +#line 1730 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 7467 "MachineIndependent/glslang_tab.cpp" +#line 7470 "MachineIndependent/glslang_tab.cpp" break; case 214: /* array_specifier: array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET */ -#line 1731 "MachineIndependent/glslang.y" +#line 1734 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-3].interm); @@ -7475,45 +7478,46 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 7479 "MachineIndependent/glslang_tab.cpp" +#line 7482 "MachineIndependent/glslang_tab.cpp" break; case 215: /* type_parameter_specifier_opt: type_parameter_specifier */ -#line 1741 "MachineIndependent/glslang.y" +#line 1744 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); } -#line 7487 "MachineIndependent/glslang_tab.cpp" +#line 7490 "MachineIndependent/glslang_tab.cpp" break; case 216: /* type_parameter_specifier_opt: %empty */ -#line 1744 "MachineIndependent/glslang.y" +#line 1747 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = 0; } -#line 7495 "MachineIndependent/glslang_tab.cpp" +#line 7498 "MachineIndependent/glslang_tab.cpp" break; case 217: /* type_parameter_specifier: LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE */ -#line 1750 "MachineIndependent/glslang.y" +#line 1753 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); } -#line 7503 "MachineIndependent/glslang_tab.cpp" +#line 7506 "MachineIndependent/glslang_tab.cpp" break; case 218: /* type_parameter_specifier_list: type_specifier */ -#line 1756 "MachineIndependent/glslang.y" +#line 1759 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = new TTypeParameters; (yyval.interm.typeParameters)->arraySizes = new TArraySizes; + (yyval.interm.typeParameters)->spirvType = (yyvsp[0].interm.type).spirvType; (yyval.interm.typeParameters)->basicType = (yyvsp[0].interm.type).basicType; } -#line 7513 "MachineIndependent/glslang_tab.cpp" +#line 7517 "MachineIndependent/glslang_tab.cpp" break; case 219: /* type_parameter_specifier_list: unary_expression */ -#line 1761 "MachineIndependent/glslang.y" +#line 1765 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = new TTypeParameters; (yyval.interm.typeParameters)->arraySizes = new TArraySizes; @@ -7522,11 +7526,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter", true); (yyval.interm.typeParameters)->arraySizes->addInnerSize(size); } -#line 7526 "MachineIndependent/glslang_tab.cpp" +#line 7530 "MachineIndependent/glslang_tab.cpp" break; case 220: /* type_parameter_specifier_list: type_parameter_specifier_list COMMA unary_expression */ -#line 1769 "MachineIndependent/glslang.y" +#line 1773 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); @@ -7534,300 +7538,300 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter", true); (yyval.interm.typeParameters)->arraySizes->addInnerSize(size); } -#line 7538 "MachineIndependent/glslang_tab.cpp" +#line 7542 "MachineIndependent/glslang_tab.cpp" break; case 221: /* type_specifier_nonarray: VOID */ -#line 1779 "MachineIndependent/glslang.y" +#line 1783 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtVoid; } -#line 7547 "MachineIndependent/glslang_tab.cpp" +#line 7551 "MachineIndependent/glslang_tab.cpp" break; case 222: /* type_specifier_nonarray: FLOAT */ -#line 1783 "MachineIndependent/glslang.y" +#line 1787 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 7556 "MachineIndependent/glslang_tab.cpp" +#line 7560 "MachineIndependent/glslang_tab.cpp" break; case 223: /* type_specifier_nonarray: INT */ -#line 1787 "MachineIndependent/glslang.y" +#line 1791 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 7565 "MachineIndependent/glslang_tab.cpp" +#line 7569 "MachineIndependent/glslang_tab.cpp" break; case 224: /* type_specifier_nonarray: UINT */ -#line 1791 "MachineIndependent/glslang.y" +#line 1795 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 7575 "MachineIndependent/glslang_tab.cpp" +#line 7579 "MachineIndependent/glslang_tab.cpp" break; case 225: /* type_specifier_nonarray: BOOL */ -#line 1796 "MachineIndependent/glslang.y" +#line 1800 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; } -#line 7584 "MachineIndependent/glslang_tab.cpp" +#line 7588 "MachineIndependent/glslang_tab.cpp" break; case 226: /* type_specifier_nonarray: VEC2 */ -#line 1800 "MachineIndependent/glslang.y" +#line 1804 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(2); } -#line 7594 "MachineIndependent/glslang_tab.cpp" +#line 7598 "MachineIndependent/glslang_tab.cpp" break; case 227: /* type_specifier_nonarray: VEC3 */ -#line 1805 "MachineIndependent/glslang.y" +#line 1809 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(3); } -#line 7604 "MachineIndependent/glslang_tab.cpp" +#line 7608 "MachineIndependent/glslang_tab.cpp" break; case 228: /* type_specifier_nonarray: VEC4 */ -#line 1810 "MachineIndependent/glslang.y" +#line 1814 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(4); } -#line 7614 "MachineIndependent/glslang_tab.cpp" +#line 7618 "MachineIndependent/glslang_tab.cpp" break; case 229: /* type_specifier_nonarray: BVEC2 */ -#line 1815 "MachineIndependent/glslang.y" +#line 1819 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(2); } -#line 7624 "MachineIndependent/glslang_tab.cpp" +#line 7628 "MachineIndependent/glslang_tab.cpp" break; case 230: /* type_specifier_nonarray: BVEC3 */ -#line 1820 "MachineIndependent/glslang.y" +#line 1824 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(3); } -#line 7634 "MachineIndependent/glslang_tab.cpp" +#line 7638 "MachineIndependent/glslang_tab.cpp" break; case 231: /* type_specifier_nonarray: BVEC4 */ -#line 1825 "MachineIndependent/glslang.y" +#line 1829 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(4); } -#line 7644 "MachineIndependent/glslang_tab.cpp" +#line 7648 "MachineIndependent/glslang_tab.cpp" break; case 232: /* type_specifier_nonarray: IVEC2 */ -#line 1830 "MachineIndependent/glslang.y" +#line 1834 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(2); } -#line 7654 "MachineIndependent/glslang_tab.cpp" +#line 7658 "MachineIndependent/glslang_tab.cpp" break; case 233: /* type_specifier_nonarray: IVEC3 */ -#line 1835 "MachineIndependent/glslang.y" +#line 1839 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 7664 "MachineIndependent/glslang_tab.cpp" +#line 7668 "MachineIndependent/glslang_tab.cpp" break; case 234: /* type_specifier_nonarray: IVEC4 */ -#line 1840 "MachineIndependent/glslang.y" +#line 1844 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 7674 "MachineIndependent/glslang_tab.cpp" +#line 7678 "MachineIndependent/glslang_tab.cpp" break; case 235: /* type_specifier_nonarray: UVEC2 */ -#line 1845 "MachineIndependent/glslang.y" +#line 1849 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 7685 "MachineIndependent/glslang_tab.cpp" +#line 7689 "MachineIndependent/glslang_tab.cpp" break; case 236: /* type_specifier_nonarray: UVEC3 */ -#line 1851 "MachineIndependent/glslang.y" +#line 1855 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 7696 "MachineIndependent/glslang_tab.cpp" +#line 7700 "MachineIndependent/glslang_tab.cpp" break; case 237: /* type_specifier_nonarray: UVEC4 */ -#line 1857 "MachineIndependent/glslang.y" +#line 1861 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 7707 "MachineIndependent/glslang_tab.cpp" +#line 7711 "MachineIndependent/glslang_tab.cpp" break; case 238: /* type_specifier_nonarray: MAT2 */ -#line 1863 "MachineIndependent/glslang.y" +#line 1867 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7717 "MachineIndependent/glslang_tab.cpp" +#line 7721 "MachineIndependent/glslang_tab.cpp" break; case 239: /* type_specifier_nonarray: MAT3 */ -#line 1868 "MachineIndependent/glslang.y" +#line 1872 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7727 "MachineIndependent/glslang_tab.cpp" +#line 7731 "MachineIndependent/glslang_tab.cpp" break; case 240: /* type_specifier_nonarray: MAT4 */ -#line 1873 "MachineIndependent/glslang.y" +#line 1877 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7737 "MachineIndependent/glslang_tab.cpp" +#line 7741 "MachineIndependent/glslang_tab.cpp" break; case 241: /* type_specifier_nonarray: MAT2X2 */ -#line 1878 "MachineIndependent/glslang.y" +#line 1882 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7747 "MachineIndependent/glslang_tab.cpp" +#line 7751 "MachineIndependent/glslang_tab.cpp" break; case 242: /* type_specifier_nonarray: MAT2X3 */ -#line 1883 "MachineIndependent/glslang.y" +#line 1887 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 7757 "MachineIndependent/glslang_tab.cpp" +#line 7761 "MachineIndependent/glslang_tab.cpp" break; case 243: /* type_specifier_nonarray: MAT2X4 */ -#line 1888 "MachineIndependent/glslang.y" +#line 1892 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 7767 "MachineIndependent/glslang_tab.cpp" +#line 7771 "MachineIndependent/glslang_tab.cpp" break; case 244: /* type_specifier_nonarray: MAT3X2 */ -#line 1893 "MachineIndependent/glslang.y" +#line 1897 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 7777 "MachineIndependent/glslang_tab.cpp" +#line 7781 "MachineIndependent/glslang_tab.cpp" break; case 245: /* type_specifier_nonarray: MAT3X3 */ -#line 1898 "MachineIndependent/glslang.y" +#line 1902 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7787 "MachineIndependent/glslang_tab.cpp" +#line 7791 "MachineIndependent/glslang_tab.cpp" break; case 246: /* type_specifier_nonarray: MAT3X4 */ -#line 1903 "MachineIndependent/glslang.y" +#line 1907 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 7797 "MachineIndependent/glslang_tab.cpp" +#line 7801 "MachineIndependent/glslang_tab.cpp" break; case 247: /* type_specifier_nonarray: MAT4X2 */ -#line 1908 "MachineIndependent/glslang.y" +#line 1912 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 7807 "MachineIndependent/glslang_tab.cpp" +#line 7811 "MachineIndependent/glslang_tab.cpp" break; case 248: /* type_specifier_nonarray: MAT4X3 */ -#line 1913 "MachineIndependent/glslang.y" +#line 1917 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 7817 "MachineIndependent/glslang_tab.cpp" +#line 7821 "MachineIndependent/glslang_tab.cpp" break; case 249: /* type_specifier_nonarray: MAT4X4 */ -#line 1918 "MachineIndependent/glslang.y" +#line 1922 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7827 "MachineIndependent/glslang_tab.cpp" +#line 7831 "MachineIndependent/glslang_tab.cpp" break; case 250: /* type_specifier_nonarray: DOUBLE */ -#line 1923 "MachineIndependent/glslang.y" +#line 1927 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7835,121 +7839,121 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 7839 "MachineIndependent/glslang_tab.cpp" +#line 7843 "MachineIndependent/glslang_tab.cpp" break; case 251: /* type_specifier_nonarray: FLOAT16_T */ -#line 1930 "MachineIndependent/glslang.y" +#line 1934 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; } -#line 7849 "MachineIndependent/glslang_tab.cpp" +#line 7853 "MachineIndependent/glslang_tab.cpp" break; case 252: /* type_specifier_nonarray: FLOAT32_T */ -#line 1935 "MachineIndependent/glslang.y" +#line 1939 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 7859 "MachineIndependent/glslang_tab.cpp" +#line 7863 "MachineIndependent/glslang_tab.cpp" break; case 253: /* type_specifier_nonarray: FLOAT64_T */ -#line 1940 "MachineIndependent/glslang.y" +#line 1944 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 7869 "MachineIndependent/glslang_tab.cpp" +#line 7873 "MachineIndependent/glslang_tab.cpp" break; case 254: /* type_specifier_nonarray: INT8_T */ -#line 1945 "MachineIndependent/glslang.y" +#line 1949 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; } -#line 7879 "MachineIndependent/glslang_tab.cpp" +#line 7883 "MachineIndependent/glslang_tab.cpp" break; case 255: /* type_specifier_nonarray: UINT8_T */ -#line 1950 "MachineIndependent/glslang.y" +#line 1954 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; } -#line 7889 "MachineIndependent/glslang_tab.cpp" +#line 7893 "MachineIndependent/glslang_tab.cpp" break; case 256: /* type_specifier_nonarray: INT16_T */ -#line 1955 "MachineIndependent/glslang.y" +#line 1959 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; } -#line 7899 "MachineIndependent/glslang_tab.cpp" +#line 7903 "MachineIndependent/glslang_tab.cpp" break; case 257: /* type_specifier_nonarray: UINT16_T */ -#line 1960 "MachineIndependent/glslang.y" +#line 1964 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; } -#line 7909 "MachineIndependent/glslang_tab.cpp" +#line 7913 "MachineIndependent/glslang_tab.cpp" break; case 258: /* type_specifier_nonarray: INT32_T */ -#line 1965 "MachineIndependent/glslang.y" +#line 1969 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 7919 "MachineIndependent/glslang_tab.cpp" +#line 7923 "MachineIndependent/glslang_tab.cpp" break; case 259: /* type_specifier_nonarray: UINT32_T */ -#line 1970 "MachineIndependent/glslang.y" +#line 1974 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 7929 "MachineIndependent/glslang_tab.cpp" +#line 7933 "MachineIndependent/glslang_tab.cpp" break; case 260: /* type_specifier_nonarray: INT64_T */ -#line 1975 "MachineIndependent/glslang.y" +#line 1979 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; } -#line 7939 "MachineIndependent/glslang_tab.cpp" +#line 7943 "MachineIndependent/glslang_tab.cpp" break; case 261: /* type_specifier_nonarray: UINT64_T */ -#line 1980 "MachineIndependent/glslang.y" +#line 1984 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; } -#line 7949 "MachineIndependent/glslang_tab.cpp" +#line 7953 "MachineIndependent/glslang_tab.cpp" break; case 262: /* type_specifier_nonarray: DVEC2 */ -#line 1985 "MachineIndependent/glslang.y" +#line 1989 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7958,11 +7962,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 7962 "MachineIndependent/glslang_tab.cpp" +#line 7966 "MachineIndependent/glslang_tab.cpp" break; case 263: /* type_specifier_nonarray: DVEC3 */ -#line 1993 "MachineIndependent/glslang.y" +#line 1997 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7971,11 +7975,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 7975 "MachineIndependent/glslang_tab.cpp" +#line 7979 "MachineIndependent/glslang_tab.cpp" break; case 264: /* type_specifier_nonarray: DVEC4 */ -#line 2001 "MachineIndependent/glslang.y" +#line 2005 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7984,374 +7988,374 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 7988 "MachineIndependent/glslang_tab.cpp" +#line 7992 "MachineIndependent/glslang_tab.cpp" break; case 265: /* type_specifier_nonarray: F16VEC2 */ -#line 2009 "MachineIndependent/glslang.y" +#line 2013 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(2); } -#line 7999 "MachineIndependent/glslang_tab.cpp" +#line 8003 "MachineIndependent/glslang_tab.cpp" break; case 266: /* type_specifier_nonarray: F16VEC3 */ -#line 2015 "MachineIndependent/glslang.y" +#line 2019 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(3); } -#line 8010 "MachineIndependent/glslang_tab.cpp" +#line 8014 "MachineIndependent/glslang_tab.cpp" break; case 267: /* type_specifier_nonarray: F16VEC4 */ -#line 2021 "MachineIndependent/glslang.y" +#line 2025 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(4); } -#line 8021 "MachineIndependent/glslang_tab.cpp" +#line 8025 "MachineIndependent/glslang_tab.cpp" break; case 268: /* type_specifier_nonarray: F32VEC2 */ -#line 2027 "MachineIndependent/glslang.y" +#line 2031 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(2); } -#line 8032 "MachineIndependent/glslang_tab.cpp" +#line 8036 "MachineIndependent/glslang_tab.cpp" break; case 269: /* type_specifier_nonarray: F32VEC3 */ -#line 2033 "MachineIndependent/glslang.y" +#line 2037 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(3); } -#line 8043 "MachineIndependent/glslang_tab.cpp" +#line 8047 "MachineIndependent/glslang_tab.cpp" break; case 270: /* type_specifier_nonarray: F32VEC4 */ -#line 2039 "MachineIndependent/glslang.y" +#line 2043 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(4); } -#line 8054 "MachineIndependent/glslang_tab.cpp" +#line 8058 "MachineIndependent/glslang_tab.cpp" break; case 271: /* type_specifier_nonarray: F64VEC2 */ -#line 2045 "MachineIndependent/glslang.y" +#line 2049 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 8065 "MachineIndependent/glslang_tab.cpp" +#line 8069 "MachineIndependent/glslang_tab.cpp" break; case 272: /* type_specifier_nonarray: F64VEC3 */ -#line 2051 "MachineIndependent/glslang.y" +#line 2055 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 8076 "MachineIndependent/glslang_tab.cpp" +#line 8080 "MachineIndependent/glslang_tab.cpp" break; case 273: /* type_specifier_nonarray: F64VEC4 */ -#line 2057 "MachineIndependent/glslang.y" +#line 2061 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 8087 "MachineIndependent/glslang_tab.cpp" +#line 8091 "MachineIndependent/glslang_tab.cpp" break; case 274: /* type_specifier_nonarray: I8VEC2 */ -#line 2063 "MachineIndependent/glslang.y" +#line 2067 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(2); } -#line 8098 "MachineIndependent/glslang_tab.cpp" +#line 8102 "MachineIndependent/glslang_tab.cpp" break; case 275: /* type_specifier_nonarray: I8VEC3 */ -#line 2069 "MachineIndependent/glslang.y" +#line 2073 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(3); } -#line 8109 "MachineIndependent/glslang_tab.cpp" +#line 8113 "MachineIndependent/glslang_tab.cpp" break; case 276: /* type_specifier_nonarray: I8VEC4 */ -#line 2075 "MachineIndependent/glslang.y" +#line 2079 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(4); } -#line 8120 "MachineIndependent/glslang_tab.cpp" +#line 8124 "MachineIndependent/glslang_tab.cpp" break; case 277: /* type_specifier_nonarray: I16VEC2 */ -#line 2081 "MachineIndependent/glslang.y" +#line 2085 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(2); } -#line 8131 "MachineIndependent/glslang_tab.cpp" +#line 8135 "MachineIndependent/glslang_tab.cpp" break; case 278: /* type_specifier_nonarray: I16VEC3 */ -#line 2087 "MachineIndependent/glslang.y" +#line 2091 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(3); } -#line 8142 "MachineIndependent/glslang_tab.cpp" +#line 8146 "MachineIndependent/glslang_tab.cpp" break; case 279: /* type_specifier_nonarray: I16VEC4 */ -#line 2093 "MachineIndependent/glslang.y" +#line 2097 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(4); } -#line 8153 "MachineIndependent/glslang_tab.cpp" +#line 8157 "MachineIndependent/glslang_tab.cpp" break; case 280: /* type_specifier_nonarray: I32VEC2 */ -#line 2099 "MachineIndependent/glslang.y" +#line 2103 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(2); } -#line 8164 "MachineIndependent/glslang_tab.cpp" +#line 8168 "MachineIndependent/glslang_tab.cpp" break; case 281: /* type_specifier_nonarray: I32VEC3 */ -#line 2105 "MachineIndependent/glslang.y" +#line 2109 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 8175 "MachineIndependent/glslang_tab.cpp" +#line 8179 "MachineIndependent/glslang_tab.cpp" break; case 282: /* type_specifier_nonarray: I32VEC4 */ -#line 2111 "MachineIndependent/glslang.y" +#line 2115 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 8186 "MachineIndependent/glslang_tab.cpp" +#line 8190 "MachineIndependent/glslang_tab.cpp" break; case 283: /* type_specifier_nonarray: I64VEC2 */ -#line 2117 "MachineIndependent/glslang.y" +#line 2121 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(2); } -#line 8197 "MachineIndependent/glslang_tab.cpp" +#line 8201 "MachineIndependent/glslang_tab.cpp" break; case 284: /* type_specifier_nonarray: I64VEC3 */ -#line 2123 "MachineIndependent/glslang.y" +#line 2127 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(3); } -#line 8208 "MachineIndependent/glslang_tab.cpp" +#line 8212 "MachineIndependent/glslang_tab.cpp" break; case 285: /* type_specifier_nonarray: I64VEC4 */ -#line 2129 "MachineIndependent/glslang.y" +#line 2133 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(4); } -#line 8219 "MachineIndependent/glslang_tab.cpp" +#line 8223 "MachineIndependent/glslang_tab.cpp" break; case 286: /* type_specifier_nonarray: U8VEC2 */ -#line 2135 "MachineIndependent/glslang.y" +#line 2139 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(2); } -#line 8230 "MachineIndependent/glslang_tab.cpp" +#line 8234 "MachineIndependent/glslang_tab.cpp" break; case 287: /* type_specifier_nonarray: U8VEC3 */ -#line 2141 "MachineIndependent/glslang.y" +#line 2145 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(3); } -#line 8241 "MachineIndependent/glslang_tab.cpp" +#line 8245 "MachineIndependent/glslang_tab.cpp" break; case 288: /* type_specifier_nonarray: U8VEC4 */ -#line 2147 "MachineIndependent/glslang.y" +#line 2151 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(4); } -#line 8252 "MachineIndependent/glslang_tab.cpp" +#line 8256 "MachineIndependent/glslang_tab.cpp" break; case 289: /* type_specifier_nonarray: U16VEC2 */ -#line 2153 "MachineIndependent/glslang.y" +#line 2157 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(2); } -#line 8263 "MachineIndependent/glslang_tab.cpp" +#line 8267 "MachineIndependent/glslang_tab.cpp" break; case 290: /* type_specifier_nonarray: U16VEC3 */ -#line 2159 "MachineIndependent/glslang.y" +#line 2163 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(3); } -#line 8274 "MachineIndependent/glslang_tab.cpp" +#line 8278 "MachineIndependent/glslang_tab.cpp" break; case 291: /* type_specifier_nonarray: U16VEC4 */ -#line 2165 "MachineIndependent/glslang.y" +#line 2169 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(4); } -#line 8285 "MachineIndependent/glslang_tab.cpp" +#line 8289 "MachineIndependent/glslang_tab.cpp" break; case 292: /* type_specifier_nonarray: U32VEC2 */ -#line 2171 "MachineIndependent/glslang.y" +#line 2175 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 8296 "MachineIndependent/glslang_tab.cpp" +#line 8300 "MachineIndependent/glslang_tab.cpp" break; case 293: /* type_specifier_nonarray: U32VEC3 */ -#line 2177 "MachineIndependent/glslang.y" +#line 2181 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 8307 "MachineIndependent/glslang_tab.cpp" +#line 8311 "MachineIndependent/glslang_tab.cpp" break; case 294: /* type_specifier_nonarray: U32VEC4 */ -#line 2183 "MachineIndependent/glslang.y" +#line 2187 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 8318 "MachineIndependent/glslang_tab.cpp" +#line 8322 "MachineIndependent/glslang_tab.cpp" break; case 295: /* type_specifier_nonarray: U64VEC2 */ -#line 2189 "MachineIndependent/glslang.y" +#line 2193 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(2); } -#line 8329 "MachineIndependent/glslang_tab.cpp" +#line 8333 "MachineIndependent/glslang_tab.cpp" break; case 296: /* type_specifier_nonarray: U64VEC3 */ -#line 2195 "MachineIndependent/glslang.y" +#line 2199 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(3); } -#line 8340 "MachineIndependent/glslang_tab.cpp" +#line 8344 "MachineIndependent/glslang_tab.cpp" break; case 297: /* type_specifier_nonarray: U64VEC4 */ -#line 2201 "MachineIndependent/glslang.y" +#line 2205 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(4); } -#line 8351 "MachineIndependent/glslang_tab.cpp" +#line 8355 "MachineIndependent/glslang_tab.cpp" break; case 298: /* type_specifier_nonarray: DMAT2 */ -#line 2207 "MachineIndependent/glslang.y" +#line 2211 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8360,11 +8364,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8364 "MachineIndependent/glslang_tab.cpp" +#line 8368 "MachineIndependent/glslang_tab.cpp" break; case 299: /* type_specifier_nonarray: DMAT3 */ -#line 2215 "MachineIndependent/glslang.y" +#line 2219 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8373,11 +8377,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8377 "MachineIndependent/glslang_tab.cpp" +#line 8381 "MachineIndependent/glslang_tab.cpp" break; case 300: /* type_specifier_nonarray: DMAT4 */ -#line 2223 "MachineIndependent/glslang.y" +#line 2227 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8386,11 +8390,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8390 "MachineIndependent/glslang_tab.cpp" +#line 8394 "MachineIndependent/glslang_tab.cpp" break; case 301: /* type_specifier_nonarray: DMAT2X2 */ -#line 2231 "MachineIndependent/glslang.y" +#line 2235 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8399,11 +8403,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8403 "MachineIndependent/glslang_tab.cpp" +#line 8407 "MachineIndependent/glslang_tab.cpp" break; case 302: /* type_specifier_nonarray: DMAT2X3 */ -#line 2239 "MachineIndependent/glslang.y" +#line 2243 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8412,11 +8416,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 8416 "MachineIndependent/glslang_tab.cpp" +#line 8420 "MachineIndependent/glslang_tab.cpp" break; case 303: /* type_specifier_nonarray: DMAT2X4 */ -#line 2247 "MachineIndependent/glslang.y" +#line 2251 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8425,11 +8429,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 8429 "MachineIndependent/glslang_tab.cpp" +#line 8433 "MachineIndependent/glslang_tab.cpp" break; case 304: /* type_specifier_nonarray: DMAT3X2 */ -#line 2255 "MachineIndependent/glslang.y" +#line 2259 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8438,11 +8442,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 8442 "MachineIndependent/glslang_tab.cpp" +#line 8446 "MachineIndependent/glslang_tab.cpp" break; case 305: /* type_specifier_nonarray: DMAT3X3 */ -#line 2263 "MachineIndependent/glslang.y" +#line 2267 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8451,11 +8455,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8455 "MachineIndependent/glslang_tab.cpp" +#line 8459 "MachineIndependent/glslang_tab.cpp" break; case 306: /* type_specifier_nonarray: DMAT3X4 */ -#line 2271 "MachineIndependent/glslang.y" +#line 2275 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8464,11 +8468,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 8468 "MachineIndependent/glslang_tab.cpp" +#line 8472 "MachineIndependent/glslang_tab.cpp" break; case 307: /* type_specifier_nonarray: DMAT4X2 */ -#line 2279 "MachineIndependent/glslang.y" +#line 2283 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8477,11 +8481,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 8481 "MachineIndependent/glslang_tab.cpp" +#line 8485 "MachineIndependent/glslang_tab.cpp" break; case 308: /* type_specifier_nonarray: DMAT4X3 */ -#line 2287 "MachineIndependent/glslang.y" +#line 2291 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8490,11 +8494,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 8494 "MachineIndependent/glslang_tab.cpp" +#line 8498 "MachineIndependent/glslang_tab.cpp" break; case 309: /* type_specifier_nonarray: DMAT4X4 */ -#line 2295 "MachineIndependent/glslang.y" +#line 2299 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8503,2261 +8507,2261 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8507 "MachineIndependent/glslang_tab.cpp" +#line 8511 "MachineIndependent/glslang_tab.cpp" break; case 310: /* type_specifier_nonarray: F16MAT2 */ -#line 2303 "MachineIndependent/glslang.y" +#line 2307 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 8518 "MachineIndependent/glslang_tab.cpp" +#line 8522 "MachineIndependent/glslang_tab.cpp" break; case 311: /* type_specifier_nonarray: F16MAT3 */ -#line 2309 "MachineIndependent/glslang.y" +#line 2313 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 8529 "MachineIndependent/glslang_tab.cpp" +#line 8533 "MachineIndependent/glslang_tab.cpp" break; case 312: /* type_specifier_nonarray: F16MAT4 */ -#line 2315 "MachineIndependent/glslang.y" +#line 2319 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 8540 "MachineIndependent/glslang_tab.cpp" +#line 8544 "MachineIndependent/glslang_tab.cpp" break; case 313: /* type_specifier_nonarray: F16MAT2X2 */ -#line 2321 "MachineIndependent/glslang.y" +#line 2325 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 8551 "MachineIndependent/glslang_tab.cpp" +#line 8555 "MachineIndependent/glslang_tab.cpp" break; case 314: /* type_specifier_nonarray: F16MAT2X3 */ -#line 2327 "MachineIndependent/glslang.y" +#line 2331 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 3); } -#line 8562 "MachineIndependent/glslang_tab.cpp" +#line 8566 "MachineIndependent/glslang_tab.cpp" break; case 315: /* type_specifier_nonarray: F16MAT2X4 */ -#line 2333 "MachineIndependent/glslang.y" +#line 2337 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 4); } -#line 8573 "MachineIndependent/glslang_tab.cpp" +#line 8577 "MachineIndependent/glslang_tab.cpp" break; case 316: /* type_specifier_nonarray: F16MAT3X2 */ -#line 2339 "MachineIndependent/glslang.y" +#line 2343 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 2); } -#line 8584 "MachineIndependent/glslang_tab.cpp" +#line 8588 "MachineIndependent/glslang_tab.cpp" break; case 317: /* type_specifier_nonarray: F16MAT3X3 */ -#line 2345 "MachineIndependent/glslang.y" +#line 2349 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 8595 "MachineIndependent/glslang_tab.cpp" +#line 8599 "MachineIndependent/glslang_tab.cpp" break; case 318: /* type_specifier_nonarray: F16MAT3X4 */ -#line 2351 "MachineIndependent/glslang.y" +#line 2355 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 4); } -#line 8606 "MachineIndependent/glslang_tab.cpp" +#line 8610 "MachineIndependent/glslang_tab.cpp" break; case 319: /* type_specifier_nonarray: F16MAT4X2 */ -#line 2357 "MachineIndependent/glslang.y" +#line 2361 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 2); } -#line 8617 "MachineIndependent/glslang_tab.cpp" +#line 8621 "MachineIndependent/glslang_tab.cpp" break; case 320: /* type_specifier_nonarray: F16MAT4X3 */ -#line 2363 "MachineIndependent/glslang.y" +#line 2367 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 3); } -#line 8628 "MachineIndependent/glslang_tab.cpp" +#line 8632 "MachineIndependent/glslang_tab.cpp" break; case 321: /* type_specifier_nonarray: F16MAT4X4 */ -#line 2369 "MachineIndependent/glslang.y" +#line 2373 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 8639 "MachineIndependent/glslang_tab.cpp" +#line 8643 "MachineIndependent/glslang_tab.cpp" break; case 322: /* type_specifier_nonarray: F32MAT2 */ -#line 2375 "MachineIndependent/glslang.y" +#line 2379 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 8650 "MachineIndependent/glslang_tab.cpp" +#line 8654 "MachineIndependent/glslang_tab.cpp" break; case 323: /* type_specifier_nonarray: F32MAT3 */ -#line 2381 "MachineIndependent/glslang.y" +#line 2385 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 8661 "MachineIndependent/glslang_tab.cpp" +#line 8665 "MachineIndependent/glslang_tab.cpp" break; case 324: /* type_specifier_nonarray: F32MAT4 */ -#line 2387 "MachineIndependent/glslang.y" +#line 2391 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 8672 "MachineIndependent/glslang_tab.cpp" +#line 8676 "MachineIndependent/glslang_tab.cpp" break; case 325: /* type_specifier_nonarray: F32MAT2X2 */ -#line 2393 "MachineIndependent/glslang.y" +#line 2397 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 8683 "MachineIndependent/glslang_tab.cpp" +#line 8687 "MachineIndependent/glslang_tab.cpp" break; case 326: /* type_specifier_nonarray: F32MAT2X3 */ -#line 2399 "MachineIndependent/glslang.y" +#line 2403 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 8694 "MachineIndependent/glslang_tab.cpp" +#line 8698 "MachineIndependent/glslang_tab.cpp" break; case 327: /* type_specifier_nonarray: F32MAT2X4 */ -#line 2405 "MachineIndependent/glslang.y" +#line 2409 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 8705 "MachineIndependent/glslang_tab.cpp" +#line 8709 "MachineIndependent/glslang_tab.cpp" break; case 328: /* type_specifier_nonarray: F32MAT3X2 */ -#line 2411 "MachineIndependent/glslang.y" +#line 2415 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 8716 "MachineIndependent/glslang_tab.cpp" +#line 8720 "MachineIndependent/glslang_tab.cpp" break; case 329: /* type_specifier_nonarray: F32MAT3X3 */ -#line 2417 "MachineIndependent/glslang.y" +#line 2421 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 8727 "MachineIndependent/glslang_tab.cpp" +#line 8731 "MachineIndependent/glslang_tab.cpp" break; case 330: /* type_specifier_nonarray: F32MAT3X4 */ -#line 2423 "MachineIndependent/glslang.y" +#line 2427 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 8738 "MachineIndependent/glslang_tab.cpp" +#line 8742 "MachineIndependent/glslang_tab.cpp" break; case 331: /* type_specifier_nonarray: F32MAT4X2 */ -#line 2429 "MachineIndependent/glslang.y" +#line 2433 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 8749 "MachineIndependent/glslang_tab.cpp" +#line 8753 "MachineIndependent/glslang_tab.cpp" break; case 332: /* type_specifier_nonarray: F32MAT4X3 */ -#line 2435 "MachineIndependent/glslang.y" +#line 2439 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 8760 "MachineIndependent/glslang_tab.cpp" +#line 8764 "MachineIndependent/glslang_tab.cpp" break; case 333: /* type_specifier_nonarray: F32MAT4X4 */ -#line 2441 "MachineIndependent/glslang.y" +#line 2445 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 8771 "MachineIndependent/glslang_tab.cpp" +#line 8775 "MachineIndependent/glslang_tab.cpp" break; case 334: /* type_specifier_nonarray: F64MAT2 */ -#line 2447 "MachineIndependent/glslang.y" +#line 2451 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8782 "MachineIndependent/glslang_tab.cpp" +#line 8786 "MachineIndependent/glslang_tab.cpp" break; case 335: /* type_specifier_nonarray: F64MAT3 */ -#line 2453 "MachineIndependent/glslang.y" +#line 2457 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8793 "MachineIndependent/glslang_tab.cpp" +#line 8797 "MachineIndependent/glslang_tab.cpp" break; case 336: /* type_specifier_nonarray: F64MAT4 */ -#line 2459 "MachineIndependent/glslang.y" +#line 2463 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8804 "MachineIndependent/glslang_tab.cpp" +#line 8808 "MachineIndependent/glslang_tab.cpp" break; case 337: /* type_specifier_nonarray: F64MAT2X2 */ -#line 2465 "MachineIndependent/glslang.y" +#line 2469 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8815 "MachineIndependent/glslang_tab.cpp" +#line 8819 "MachineIndependent/glslang_tab.cpp" break; case 338: /* type_specifier_nonarray: F64MAT2X3 */ -#line 2471 "MachineIndependent/glslang.y" +#line 2475 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 8826 "MachineIndependent/glslang_tab.cpp" +#line 8830 "MachineIndependent/glslang_tab.cpp" break; case 339: /* type_specifier_nonarray: F64MAT2X4 */ -#line 2477 "MachineIndependent/glslang.y" +#line 2481 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 8837 "MachineIndependent/glslang_tab.cpp" +#line 8841 "MachineIndependent/glslang_tab.cpp" break; case 340: /* type_specifier_nonarray: F64MAT3X2 */ -#line 2483 "MachineIndependent/glslang.y" +#line 2487 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 8848 "MachineIndependent/glslang_tab.cpp" +#line 8852 "MachineIndependent/glslang_tab.cpp" break; case 341: /* type_specifier_nonarray: F64MAT3X3 */ -#line 2489 "MachineIndependent/glslang.y" +#line 2493 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8859 "MachineIndependent/glslang_tab.cpp" +#line 8863 "MachineIndependent/glslang_tab.cpp" break; case 342: /* type_specifier_nonarray: F64MAT3X4 */ -#line 2495 "MachineIndependent/glslang.y" +#line 2499 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 8870 "MachineIndependent/glslang_tab.cpp" +#line 8874 "MachineIndependent/glslang_tab.cpp" break; case 343: /* type_specifier_nonarray: F64MAT4X2 */ -#line 2501 "MachineIndependent/glslang.y" +#line 2505 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 8881 "MachineIndependent/glslang_tab.cpp" +#line 8885 "MachineIndependent/glslang_tab.cpp" break; case 344: /* type_specifier_nonarray: F64MAT4X3 */ -#line 2507 "MachineIndependent/glslang.y" +#line 2511 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 8892 "MachineIndependent/glslang_tab.cpp" +#line 8896 "MachineIndependent/glslang_tab.cpp" break; case 345: /* type_specifier_nonarray: F64MAT4X4 */ -#line 2513 "MachineIndependent/glslang.y" +#line 2517 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8903 "MachineIndependent/glslang_tab.cpp" +#line 8907 "MachineIndependent/glslang_tab.cpp" break; case 346: /* type_specifier_nonarray: ACCSTRUCTNV */ -#line 2519 "MachineIndependent/glslang.y" +#line 2523 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAccStruct; } -#line 8912 "MachineIndependent/glslang_tab.cpp" +#line 8916 "MachineIndependent/glslang_tab.cpp" break; case 347: /* type_specifier_nonarray: ACCSTRUCTEXT */ -#line 2523 "MachineIndependent/glslang.y" +#line 2527 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAccStruct; } -#line 8921 "MachineIndependent/glslang_tab.cpp" +#line 8925 "MachineIndependent/glslang_tab.cpp" break; case 348: /* type_specifier_nonarray: RAYQUERYEXT */ -#line 2527 "MachineIndependent/glslang.y" +#line 2531 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtRayQuery; } -#line 8930 "MachineIndependent/glslang_tab.cpp" +#line 8934 "MachineIndependent/glslang_tab.cpp" break; case 349: /* type_specifier_nonarray: ATOMIC_UINT */ -#line 2531 "MachineIndependent/glslang.y" +#line 2535 "MachineIndependent/glslang.y" { parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAtomicUint; } -#line 8940 "MachineIndependent/glslang_tab.cpp" +#line 8944 "MachineIndependent/glslang_tab.cpp" break; case 350: /* type_specifier_nonarray: SAMPLER1D */ -#line 2536 "MachineIndependent/glslang.y" +#line 2540 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D); } -#line 8950 "MachineIndependent/glslang_tab.cpp" +#line 8954 "MachineIndependent/glslang_tab.cpp" break; case 351: /* type_specifier_nonarray: SAMPLER2D */ -#line 2541 "MachineIndependent/glslang.y" +#line 2545 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); } -#line 8960 "MachineIndependent/glslang_tab.cpp" +#line 8964 "MachineIndependent/glslang_tab.cpp" break; case 352: /* type_specifier_nonarray: SAMPLER3D */ -#line 2546 "MachineIndependent/glslang.y" +#line 2550 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd3D); } -#line 8970 "MachineIndependent/glslang_tab.cpp" +#line 8974 "MachineIndependent/glslang_tab.cpp" break; case 353: /* type_specifier_nonarray: SAMPLERCUBE */ -#line 2551 "MachineIndependent/glslang.y" +#line 2555 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube); } -#line 8980 "MachineIndependent/glslang_tab.cpp" +#line 8984 "MachineIndependent/glslang_tab.cpp" break; case 354: /* type_specifier_nonarray: SAMPLER2DSHADOW */ -#line 2556 "MachineIndependent/glslang.y" +#line 2560 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); } -#line 8990 "MachineIndependent/glslang_tab.cpp" +#line 8994 "MachineIndependent/glslang_tab.cpp" break; case 355: /* type_specifier_nonarray: SAMPLERCUBESHADOW */ -#line 2561 "MachineIndependent/glslang.y" +#line 2565 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); } -#line 9000 "MachineIndependent/glslang_tab.cpp" +#line 9004 "MachineIndependent/glslang_tab.cpp" break; case 356: /* type_specifier_nonarray: SAMPLER2DARRAY */ -#line 2566 "MachineIndependent/glslang.y" +#line 2570 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); } -#line 9010 "MachineIndependent/glslang_tab.cpp" +#line 9014 "MachineIndependent/glslang_tab.cpp" break; case 357: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */ -#line 2571 "MachineIndependent/glslang.y" +#line 2575 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); } -#line 9020 "MachineIndependent/glslang_tab.cpp" +#line 9024 "MachineIndependent/glslang_tab.cpp" break; case 358: /* type_specifier_nonarray: SAMPLER1DSHADOW */ -#line 2576 "MachineIndependent/glslang.y" +#line 2580 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); } -#line 9030 "MachineIndependent/glslang_tab.cpp" +#line 9034 "MachineIndependent/glslang_tab.cpp" break; case 359: /* type_specifier_nonarray: SAMPLER1DARRAY */ -#line 2581 "MachineIndependent/glslang.y" +#line 2585 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); } -#line 9040 "MachineIndependent/glslang_tab.cpp" +#line 9044 "MachineIndependent/glslang_tab.cpp" break; case 360: /* type_specifier_nonarray: SAMPLER1DARRAYSHADOW */ -#line 2586 "MachineIndependent/glslang.y" +#line 2590 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); } -#line 9050 "MachineIndependent/glslang_tab.cpp" +#line 9054 "MachineIndependent/glslang_tab.cpp" break; case 361: /* type_specifier_nonarray: SAMPLERCUBEARRAY */ -#line 2591 "MachineIndependent/glslang.y" +#line 2595 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); } -#line 9060 "MachineIndependent/glslang_tab.cpp" +#line 9064 "MachineIndependent/glslang_tab.cpp" break; case 362: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOW */ -#line 2596 "MachineIndependent/glslang.y" +#line 2600 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); } -#line 9070 "MachineIndependent/glslang_tab.cpp" +#line 9074 "MachineIndependent/glslang_tab.cpp" break; case 363: /* type_specifier_nonarray: F16SAMPLER1D */ -#line 2601 "MachineIndependent/glslang.y" +#line 2605 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D); } -#line 9081 "MachineIndependent/glslang_tab.cpp" +#line 9085 "MachineIndependent/glslang_tab.cpp" break; case 364: /* type_specifier_nonarray: F16SAMPLER2D */ -#line 2607 "MachineIndependent/glslang.y" +#line 2611 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D); } -#line 9092 "MachineIndependent/glslang_tab.cpp" +#line 9096 "MachineIndependent/glslang_tab.cpp" break; case 365: /* type_specifier_nonarray: F16SAMPLER3D */ -#line 2613 "MachineIndependent/glslang.y" +#line 2617 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd3D); } -#line 9103 "MachineIndependent/glslang_tab.cpp" +#line 9107 "MachineIndependent/glslang_tab.cpp" break; case 366: /* type_specifier_nonarray: F16SAMPLERCUBE */ -#line 2619 "MachineIndependent/glslang.y" +#line 2623 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube); } -#line 9114 "MachineIndependent/glslang_tab.cpp" +#line 9118 "MachineIndependent/glslang_tab.cpp" break; case 367: /* type_specifier_nonarray: F16SAMPLER1DSHADOW */ -#line 2625 "MachineIndependent/glslang.y" +#line 2629 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, false, true); } -#line 9125 "MachineIndependent/glslang_tab.cpp" +#line 9129 "MachineIndependent/glslang_tab.cpp" break; case 368: /* type_specifier_nonarray: F16SAMPLER2DSHADOW */ -#line 2631 "MachineIndependent/glslang.y" +#line 2635 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, true); } -#line 9136 "MachineIndependent/glslang_tab.cpp" +#line 9140 "MachineIndependent/glslang_tab.cpp" break; case 369: /* type_specifier_nonarray: F16SAMPLERCUBESHADOW */ -#line 2637 "MachineIndependent/glslang.y" +#line 2641 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, false, true); } -#line 9147 "MachineIndependent/glslang_tab.cpp" +#line 9151 "MachineIndependent/glslang_tab.cpp" break; case 370: /* type_specifier_nonarray: F16SAMPLER1DARRAY */ -#line 2643 "MachineIndependent/glslang.y" +#line 2647 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true); } -#line 9158 "MachineIndependent/glslang_tab.cpp" +#line 9162 "MachineIndependent/glslang_tab.cpp" break; case 371: /* type_specifier_nonarray: F16SAMPLER2DARRAY */ -#line 2649 "MachineIndependent/glslang.y" +#line 2653 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true); } -#line 9169 "MachineIndependent/glslang_tab.cpp" +#line 9173 "MachineIndependent/glslang_tab.cpp" break; case 372: /* type_specifier_nonarray: F16SAMPLER1DARRAYSHADOW */ -#line 2655 "MachineIndependent/glslang.y" +#line 2659 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true, true); } -#line 9180 "MachineIndependent/glslang_tab.cpp" +#line 9184 "MachineIndependent/glslang_tab.cpp" break; case 373: /* type_specifier_nonarray: F16SAMPLER2DARRAYSHADOW */ -#line 2661 "MachineIndependent/glslang.y" +#line 2665 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, true); } -#line 9191 "MachineIndependent/glslang_tab.cpp" +#line 9195 "MachineIndependent/glslang_tab.cpp" break; case 374: /* type_specifier_nonarray: F16SAMPLERCUBEARRAY */ -#line 2667 "MachineIndependent/glslang.y" +#line 2671 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true); } -#line 9202 "MachineIndependent/glslang_tab.cpp" +#line 9206 "MachineIndependent/glslang_tab.cpp" break; case 375: /* type_specifier_nonarray: F16SAMPLERCUBEARRAYSHADOW */ -#line 2673 "MachineIndependent/glslang.y" +#line 2677 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true, true); } -#line 9213 "MachineIndependent/glslang_tab.cpp" +#line 9217 "MachineIndependent/glslang_tab.cpp" break; case 376: /* type_specifier_nonarray: ISAMPLER1D */ -#line 2679 "MachineIndependent/glslang.y" +#line 2683 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D); } -#line 9223 "MachineIndependent/glslang_tab.cpp" +#line 9227 "MachineIndependent/glslang_tab.cpp" break; case 377: /* type_specifier_nonarray: ISAMPLER2D */ -#line 2684 "MachineIndependent/glslang.y" +#line 2688 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D); } -#line 9233 "MachineIndependent/glslang_tab.cpp" +#line 9237 "MachineIndependent/glslang_tab.cpp" break; case 378: /* type_specifier_nonarray: ISAMPLER3D */ -#line 2689 "MachineIndependent/glslang.y" +#line 2693 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd3D); } -#line 9243 "MachineIndependent/glslang_tab.cpp" +#line 9247 "MachineIndependent/glslang_tab.cpp" break; case 379: /* type_specifier_nonarray: ISAMPLERCUBE */ -#line 2694 "MachineIndependent/glslang.y" +#line 2698 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube); } -#line 9253 "MachineIndependent/glslang_tab.cpp" +#line 9257 "MachineIndependent/glslang_tab.cpp" break; case 380: /* type_specifier_nonarray: ISAMPLER2DARRAY */ -#line 2699 "MachineIndependent/glslang.y" +#line 2703 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); } -#line 9263 "MachineIndependent/glslang_tab.cpp" +#line 9267 "MachineIndependent/glslang_tab.cpp" break; case 381: /* type_specifier_nonarray: USAMPLER2D */ -#line 2704 "MachineIndependent/glslang.y" +#line 2708 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D); } -#line 9273 "MachineIndependent/glslang_tab.cpp" +#line 9277 "MachineIndependent/glslang_tab.cpp" break; case 382: /* type_specifier_nonarray: USAMPLER3D */ -#line 2709 "MachineIndependent/glslang.y" +#line 2713 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd3D); } -#line 9283 "MachineIndependent/glslang_tab.cpp" +#line 9287 "MachineIndependent/glslang_tab.cpp" break; case 383: /* type_specifier_nonarray: USAMPLERCUBE */ -#line 2714 "MachineIndependent/glslang.y" +#line 2718 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube); } -#line 9293 "MachineIndependent/glslang_tab.cpp" +#line 9297 "MachineIndependent/glslang_tab.cpp" break; case 384: /* type_specifier_nonarray: ISAMPLER1DARRAY */ -#line 2719 "MachineIndependent/glslang.y" +#line 2723 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); } -#line 9303 "MachineIndependent/glslang_tab.cpp" +#line 9307 "MachineIndependent/glslang_tab.cpp" break; case 385: /* type_specifier_nonarray: ISAMPLERCUBEARRAY */ -#line 2724 "MachineIndependent/glslang.y" +#line 2728 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); } -#line 9313 "MachineIndependent/glslang_tab.cpp" +#line 9317 "MachineIndependent/glslang_tab.cpp" break; case 386: /* type_specifier_nonarray: USAMPLER1D */ -#line 2729 "MachineIndependent/glslang.y" +#line 2733 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D); } -#line 9323 "MachineIndependent/glslang_tab.cpp" +#line 9327 "MachineIndependent/glslang_tab.cpp" break; case 387: /* type_specifier_nonarray: USAMPLER1DARRAY */ -#line 2734 "MachineIndependent/glslang.y" +#line 2738 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); } -#line 9333 "MachineIndependent/glslang_tab.cpp" +#line 9337 "MachineIndependent/glslang_tab.cpp" break; case 388: /* type_specifier_nonarray: USAMPLERCUBEARRAY */ -#line 2739 "MachineIndependent/glslang.y" +#line 2743 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); } -#line 9343 "MachineIndependent/glslang_tab.cpp" +#line 9347 "MachineIndependent/glslang_tab.cpp" break; case 389: /* type_specifier_nonarray: TEXTURECUBEARRAY */ -#line 2744 "MachineIndependent/glslang.y" +#line 2748 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); } -#line 9353 "MachineIndependent/glslang_tab.cpp" +#line 9357 "MachineIndependent/glslang_tab.cpp" break; case 390: /* type_specifier_nonarray: ITEXTURECUBEARRAY */ -#line 2749 "MachineIndependent/glslang.y" +#line 2753 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); } -#line 9363 "MachineIndependent/glslang_tab.cpp" +#line 9367 "MachineIndependent/glslang_tab.cpp" break; case 391: /* type_specifier_nonarray: UTEXTURECUBEARRAY */ -#line 2754 "MachineIndependent/glslang.y" +#line 2758 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); } -#line 9373 "MachineIndependent/glslang_tab.cpp" +#line 9377 "MachineIndependent/glslang_tab.cpp" break; case 392: /* type_specifier_nonarray: USAMPLER2DARRAY */ -#line 2759 "MachineIndependent/glslang.y" +#line 2763 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); } -#line 9383 "MachineIndependent/glslang_tab.cpp" +#line 9387 "MachineIndependent/glslang_tab.cpp" break; case 393: /* type_specifier_nonarray: TEXTURE2D */ -#line 2764 "MachineIndependent/glslang.y" +#line 2768 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); } -#line 9393 "MachineIndependent/glslang_tab.cpp" +#line 9397 "MachineIndependent/glslang_tab.cpp" break; case 394: /* type_specifier_nonarray: TEXTURE3D */ -#line 2769 "MachineIndependent/glslang.y" +#line 2773 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); } -#line 9403 "MachineIndependent/glslang_tab.cpp" +#line 9407 "MachineIndependent/glslang_tab.cpp" break; case 395: /* type_specifier_nonarray: TEXTURE2DARRAY */ -#line 2774 "MachineIndependent/glslang.y" +#line 2778 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); } -#line 9413 "MachineIndependent/glslang_tab.cpp" +#line 9417 "MachineIndependent/glslang_tab.cpp" break; case 396: /* type_specifier_nonarray: TEXTURECUBE */ -#line 2779 "MachineIndependent/glslang.y" +#line 2783 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); } -#line 9423 "MachineIndependent/glslang_tab.cpp" +#line 9427 "MachineIndependent/glslang_tab.cpp" break; case 397: /* type_specifier_nonarray: ITEXTURE2D */ -#line 2784 "MachineIndependent/glslang.y" +#line 2788 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); } -#line 9433 "MachineIndependent/glslang_tab.cpp" +#line 9437 "MachineIndependent/glslang_tab.cpp" break; case 398: /* type_specifier_nonarray: ITEXTURE3D */ -#line 2789 "MachineIndependent/glslang.y" +#line 2793 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); } -#line 9443 "MachineIndependent/glslang_tab.cpp" +#line 9447 "MachineIndependent/glslang_tab.cpp" break; case 399: /* type_specifier_nonarray: ITEXTURECUBE */ -#line 2794 "MachineIndependent/glslang.y" +#line 2798 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); } -#line 9453 "MachineIndependent/glslang_tab.cpp" +#line 9457 "MachineIndependent/glslang_tab.cpp" break; case 400: /* type_specifier_nonarray: ITEXTURE2DARRAY */ -#line 2799 "MachineIndependent/glslang.y" +#line 2803 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); } -#line 9463 "MachineIndependent/glslang_tab.cpp" +#line 9467 "MachineIndependent/glslang_tab.cpp" break; case 401: /* type_specifier_nonarray: UTEXTURE2D */ -#line 2804 "MachineIndependent/glslang.y" +#line 2808 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); } -#line 9473 "MachineIndependent/glslang_tab.cpp" +#line 9477 "MachineIndependent/glslang_tab.cpp" break; case 402: /* type_specifier_nonarray: UTEXTURE3D */ -#line 2809 "MachineIndependent/glslang.y" +#line 2813 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); } -#line 9483 "MachineIndependent/glslang_tab.cpp" +#line 9487 "MachineIndependent/glslang_tab.cpp" break; case 403: /* type_specifier_nonarray: UTEXTURECUBE */ -#line 2814 "MachineIndependent/glslang.y" +#line 2818 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); } -#line 9493 "MachineIndependent/glslang_tab.cpp" +#line 9497 "MachineIndependent/glslang_tab.cpp" break; case 404: /* type_specifier_nonarray: UTEXTURE2DARRAY */ -#line 2819 "MachineIndependent/glslang.y" +#line 2823 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); } -#line 9503 "MachineIndependent/glslang_tab.cpp" +#line 9507 "MachineIndependent/glslang_tab.cpp" break; case 405: /* type_specifier_nonarray: SAMPLER */ -#line 2824 "MachineIndependent/glslang.y" +#line 2828 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(false); } -#line 9513 "MachineIndependent/glslang_tab.cpp" +#line 9517 "MachineIndependent/glslang_tab.cpp" break; case 406: /* type_specifier_nonarray: SAMPLERSHADOW */ -#line 2829 "MachineIndependent/glslang.y" +#line 2833 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(true); } -#line 9523 "MachineIndependent/glslang_tab.cpp" +#line 9527 "MachineIndependent/glslang_tab.cpp" break; case 407: /* type_specifier_nonarray: SAMPLER2DRECT */ -#line 2834 "MachineIndependent/glslang.y" +#line 2838 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect); } -#line 9533 "MachineIndependent/glslang_tab.cpp" +#line 9537 "MachineIndependent/glslang_tab.cpp" break; case 408: /* type_specifier_nonarray: SAMPLER2DRECTSHADOW */ -#line 2839 "MachineIndependent/glslang.y" +#line 2843 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); } -#line 9543 "MachineIndependent/glslang_tab.cpp" +#line 9547 "MachineIndependent/glslang_tab.cpp" break; case 409: /* type_specifier_nonarray: F16SAMPLER2DRECT */ -#line 2844 "MachineIndependent/glslang.y" +#line 2848 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); } -#line 9554 "MachineIndependent/glslang_tab.cpp" +#line 9558 "MachineIndependent/glslang_tab.cpp" break; case 410: /* type_specifier_nonarray: F16SAMPLER2DRECTSHADOW */ -#line 2850 "MachineIndependent/glslang.y" +#line 2854 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); } -#line 9565 "MachineIndependent/glslang_tab.cpp" +#line 9569 "MachineIndependent/glslang_tab.cpp" break; case 411: /* type_specifier_nonarray: ISAMPLER2DRECT */ -#line 2856 "MachineIndependent/glslang.y" +#line 2860 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdRect); } -#line 9575 "MachineIndependent/glslang_tab.cpp" +#line 9579 "MachineIndependent/glslang_tab.cpp" break; case 412: /* type_specifier_nonarray: USAMPLER2DRECT */ -#line 2861 "MachineIndependent/glslang.y" +#line 2865 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdRect); } -#line 9585 "MachineIndependent/glslang_tab.cpp" +#line 9589 "MachineIndependent/glslang_tab.cpp" break; case 413: /* type_specifier_nonarray: SAMPLERBUFFER */ -#line 2866 "MachineIndependent/glslang.y" +#line 2870 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); } -#line 9595 "MachineIndependent/glslang_tab.cpp" +#line 9599 "MachineIndependent/glslang_tab.cpp" break; case 414: /* type_specifier_nonarray: F16SAMPLERBUFFER */ -#line 2871 "MachineIndependent/glslang.y" +#line 2875 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); } -#line 9606 "MachineIndependent/glslang_tab.cpp" +#line 9610 "MachineIndependent/glslang_tab.cpp" break; case 415: /* type_specifier_nonarray: ISAMPLERBUFFER */ -#line 2877 "MachineIndependent/glslang.y" +#line 2881 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); } -#line 9616 "MachineIndependent/glslang_tab.cpp" +#line 9620 "MachineIndependent/glslang_tab.cpp" break; case 416: /* type_specifier_nonarray: USAMPLERBUFFER */ -#line 2882 "MachineIndependent/glslang.y" +#line 2886 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); } -#line 9626 "MachineIndependent/glslang_tab.cpp" +#line 9630 "MachineIndependent/glslang_tab.cpp" break; case 417: /* type_specifier_nonarray: SAMPLER2DMS */ -#line 2887 "MachineIndependent/glslang.y" +#line 2891 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); } -#line 9636 "MachineIndependent/glslang_tab.cpp" +#line 9640 "MachineIndependent/glslang_tab.cpp" break; case 418: /* type_specifier_nonarray: F16SAMPLER2DMS */ -#line 2892 "MachineIndependent/glslang.y" +#line 2896 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); } -#line 9647 "MachineIndependent/glslang_tab.cpp" +#line 9651 "MachineIndependent/glslang_tab.cpp" break; case 419: /* type_specifier_nonarray: ISAMPLER2DMS */ -#line 2898 "MachineIndependent/glslang.y" +#line 2902 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); } -#line 9657 "MachineIndependent/glslang_tab.cpp" +#line 9661 "MachineIndependent/glslang_tab.cpp" break; case 420: /* type_specifier_nonarray: USAMPLER2DMS */ -#line 2903 "MachineIndependent/glslang.y" +#line 2907 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); } -#line 9667 "MachineIndependent/glslang_tab.cpp" +#line 9671 "MachineIndependent/glslang_tab.cpp" break; case 421: /* type_specifier_nonarray: SAMPLER2DMSARRAY */ -#line 2908 "MachineIndependent/glslang.y" +#line 2912 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); } -#line 9677 "MachineIndependent/glslang_tab.cpp" +#line 9681 "MachineIndependent/glslang_tab.cpp" break; case 422: /* type_specifier_nonarray: F16SAMPLER2DMSARRAY */ -#line 2913 "MachineIndependent/glslang.y" +#line 2917 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); } -#line 9688 "MachineIndependent/glslang_tab.cpp" +#line 9692 "MachineIndependent/glslang_tab.cpp" break; case 423: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */ -#line 2919 "MachineIndependent/glslang.y" +#line 2923 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); } -#line 9698 "MachineIndependent/glslang_tab.cpp" +#line 9702 "MachineIndependent/glslang_tab.cpp" break; case 424: /* type_specifier_nonarray: USAMPLER2DMSARRAY */ -#line 2924 "MachineIndependent/glslang.y" +#line 2928 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); } -#line 9708 "MachineIndependent/glslang_tab.cpp" +#line 9712 "MachineIndependent/glslang_tab.cpp" break; case 425: /* type_specifier_nonarray: TEXTURE1D */ -#line 2929 "MachineIndependent/glslang.y" +#line 2933 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); } -#line 9718 "MachineIndependent/glslang_tab.cpp" +#line 9722 "MachineIndependent/glslang_tab.cpp" break; case 426: /* type_specifier_nonarray: F16TEXTURE1D */ -#line 2934 "MachineIndependent/glslang.y" +#line 2938 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); } -#line 9729 "MachineIndependent/glslang_tab.cpp" +#line 9733 "MachineIndependent/glslang_tab.cpp" break; case 427: /* type_specifier_nonarray: F16TEXTURE2D */ -#line 2940 "MachineIndependent/glslang.y" +#line 2944 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); } -#line 9740 "MachineIndependent/glslang_tab.cpp" +#line 9744 "MachineIndependent/glslang_tab.cpp" break; case 428: /* type_specifier_nonarray: F16TEXTURE3D */ -#line 2946 "MachineIndependent/glslang.y" +#line 2950 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); } -#line 9751 "MachineIndependent/glslang_tab.cpp" +#line 9755 "MachineIndependent/glslang_tab.cpp" break; case 429: /* type_specifier_nonarray: F16TEXTURECUBE */ -#line 2952 "MachineIndependent/glslang.y" +#line 2956 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); } -#line 9762 "MachineIndependent/glslang_tab.cpp" +#line 9766 "MachineIndependent/glslang_tab.cpp" break; case 430: /* type_specifier_nonarray: TEXTURE1DARRAY */ -#line 2958 "MachineIndependent/glslang.y" +#line 2962 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); } -#line 9772 "MachineIndependent/glslang_tab.cpp" +#line 9776 "MachineIndependent/glslang_tab.cpp" break; case 431: /* type_specifier_nonarray: F16TEXTURE1DARRAY */ -#line 2963 "MachineIndependent/glslang.y" +#line 2967 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); } -#line 9783 "MachineIndependent/glslang_tab.cpp" +#line 9787 "MachineIndependent/glslang_tab.cpp" break; case 432: /* type_specifier_nonarray: F16TEXTURE2DARRAY */ -#line 2969 "MachineIndependent/glslang.y" +#line 2973 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); } -#line 9794 "MachineIndependent/glslang_tab.cpp" +#line 9798 "MachineIndependent/glslang_tab.cpp" break; case 433: /* type_specifier_nonarray: F16TEXTURECUBEARRAY */ -#line 2975 "MachineIndependent/glslang.y" +#line 2979 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); } -#line 9805 "MachineIndependent/glslang_tab.cpp" +#line 9809 "MachineIndependent/glslang_tab.cpp" break; case 434: /* type_specifier_nonarray: ITEXTURE1D */ -#line 2981 "MachineIndependent/glslang.y" +#line 2985 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); } -#line 9815 "MachineIndependent/glslang_tab.cpp" +#line 9819 "MachineIndependent/glslang_tab.cpp" break; case 435: /* type_specifier_nonarray: ITEXTURE1DARRAY */ -#line 2986 "MachineIndependent/glslang.y" +#line 2990 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); } -#line 9825 "MachineIndependent/glslang_tab.cpp" +#line 9829 "MachineIndependent/glslang_tab.cpp" break; case 436: /* type_specifier_nonarray: UTEXTURE1D */ -#line 2991 "MachineIndependent/glslang.y" +#line 2995 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); } -#line 9835 "MachineIndependent/glslang_tab.cpp" +#line 9839 "MachineIndependent/glslang_tab.cpp" break; case 437: /* type_specifier_nonarray: UTEXTURE1DARRAY */ -#line 2996 "MachineIndependent/glslang.y" +#line 3000 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); } -#line 9845 "MachineIndependent/glslang_tab.cpp" +#line 9849 "MachineIndependent/glslang_tab.cpp" break; case 438: /* type_specifier_nonarray: TEXTURE2DRECT */ -#line 3001 "MachineIndependent/glslang.y" +#line 3005 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); } -#line 9855 "MachineIndependent/glslang_tab.cpp" +#line 9859 "MachineIndependent/glslang_tab.cpp" break; case 439: /* type_specifier_nonarray: F16TEXTURE2DRECT */ -#line 3006 "MachineIndependent/glslang.y" +#line 3010 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdRect); } -#line 9866 "MachineIndependent/glslang_tab.cpp" +#line 9870 "MachineIndependent/glslang_tab.cpp" break; case 440: /* type_specifier_nonarray: ITEXTURE2DRECT */ -#line 3012 "MachineIndependent/glslang.y" +#line 3016 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); } -#line 9876 "MachineIndependent/glslang_tab.cpp" +#line 9880 "MachineIndependent/glslang_tab.cpp" break; case 441: /* type_specifier_nonarray: UTEXTURE2DRECT */ -#line 3017 "MachineIndependent/glslang.y" +#line 3021 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); } -#line 9886 "MachineIndependent/glslang_tab.cpp" +#line 9890 "MachineIndependent/glslang_tab.cpp" break; case 442: /* type_specifier_nonarray: TEXTUREBUFFER */ -#line 3022 "MachineIndependent/glslang.y" +#line 3026 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); } -#line 9896 "MachineIndependent/glslang_tab.cpp" +#line 9900 "MachineIndependent/glslang_tab.cpp" break; case 443: /* type_specifier_nonarray: F16TEXTUREBUFFER */ -#line 3027 "MachineIndependent/glslang.y" +#line 3031 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdBuffer); } -#line 9907 "MachineIndependent/glslang_tab.cpp" +#line 9911 "MachineIndependent/glslang_tab.cpp" break; case 444: /* type_specifier_nonarray: ITEXTUREBUFFER */ -#line 3033 "MachineIndependent/glslang.y" +#line 3037 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); } -#line 9917 "MachineIndependent/glslang_tab.cpp" +#line 9921 "MachineIndependent/glslang_tab.cpp" break; case 445: /* type_specifier_nonarray: UTEXTUREBUFFER */ -#line 3038 "MachineIndependent/glslang.y" +#line 3042 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); } -#line 9927 "MachineIndependent/glslang_tab.cpp" +#line 9931 "MachineIndependent/glslang_tab.cpp" break; case 446: /* type_specifier_nonarray: TEXTURE2DMS */ -#line 3043 "MachineIndependent/glslang.y" +#line 3047 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); } -#line 9937 "MachineIndependent/glslang_tab.cpp" +#line 9941 "MachineIndependent/glslang_tab.cpp" break; case 447: /* type_specifier_nonarray: F16TEXTURE2DMS */ -#line 3048 "MachineIndependent/glslang.y" +#line 3052 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, false, false, true); } -#line 9948 "MachineIndependent/glslang_tab.cpp" +#line 9952 "MachineIndependent/glslang_tab.cpp" break; case 448: /* type_specifier_nonarray: ITEXTURE2DMS */ -#line 3054 "MachineIndependent/glslang.y" +#line 3058 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); } -#line 9958 "MachineIndependent/glslang_tab.cpp" +#line 9962 "MachineIndependent/glslang_tab.cpp" break; case 449: /* type_specifier_nonarray: UTEXTURE2DMS */ -#line 3059 "MachineIndependent/glslang.y" +#line 3063 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); } -#line 9968 "MachineIndependent/glslang_tab.cpp" +#line 9972 "MachineIndependent/glslang_tab.cpp" break; case 450: /* type_specifier_nonarray: TEXTURE2DMSARRAY */ -#line 3064 "MachineIndependent/glslang.y" +#line 3068 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); } -#line 9978 "MachineIndependent/glslang_tab.cpp" +#line 9982 "MachineIndependent/glslang_tab.cpp" break; case 451: /* type_specifier_nonarray: F16TEXTURE2DMSARRAY */ -#line 3069 "MachineIndependent/glslang.y" +#line 3073 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true, false, true); } -#line 9989 "MachineIndependent/glslang_tab.cpp" +#line 9993 "MachineIndependent/glslang_tab.cpp" break; case 452: /* type_specifier_nonarray: ITEXTURE2DMSARRAY */ -#line 3075 "MachineIndependent/glslang.y" +#line 3079 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); } -#line 9999 "MachineIndependent/glslang_tab.cpp" +#line 10003 "MachineIndependent/glslang_tab.cpp" break; case 453: /* type_specifier_nonarray: UTEXTURE2DMSARRAY */ -#line 3080 "MachineIndependent/glslang.y" +#line 3084 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); } -#line 10009 "MachineIndependent/glslang_tab.cpp" +#line 10013 "MachineIndependent/glslang_tab.cpp" break; case 454: /* type_specifier_nonarray: IMAGE1D */ -#line 3085 "MachineIndependent/glslang.y" +#line 3089 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); } -#line 10019 "MachineIndependent/glslang_tab.cpp" +#line 10023 "MachineIndependent/glslang_tab.cpp" break; case 455: /* type_specifier_nonarray: F16IMAGE1D */ -#line 3090 "MachineIndependent/glslang.y" +#line 3094 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D); } -#line 10030 "MachineIndependent/glslang_tab.cpp" +#line 10034 "MachineIndependent/glslang_tab.cpp" break; case 456: /* type_specifier_nonarray: IIMAGE1D */ -#line 3096 "MachineIndependent/glslang.y" +#line 3100 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); } -#line 10040 "MachineIndependent/glslang_tab.cpp" +#line 10044 "MachineIndependent/glslang_tab.cpp" break; case 457: /* type_specifier_nonarray: UIMAGE1D */ -#line 3101 "MachineIndependent/glslang.y" +#line 3105 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); } -#line 10050 "MachineIndependent/glslang_tab.cpp" +#line 10054 "MachineIndependent/glslang_tab.cpp" break; case 458: /* type_specifier_nonarray: IMAGE2D */ -#line 3106 "MachineIndependent/glslang.y" +#line 3110 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); } -#line 10060 "MachineIndependent/glslang_tab.cpp" +#line 10064 "MachineIndependent/glslang_tab.cpp" break; case 459: /* type_specifier_nonarray: F16IMAGE2D */ -#line 3111 "MachineIndependent/glslang.y" +#line 3115 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D); } -#line 10071 "MachineIndependent/glslang_tab.cpp" +#line 10075 "MachineIndependent/glslang_tab.cpp" break; case 460: /* type_specifier_nonarray: IIMAGE2D */ -#line 3117 "MachineIndependent/glslang.y" +#line 3121 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); } -#line 10081 "MachineIndependent/glslang_tab.cpp" +#line 10085 "MachineIndependent/glslang_tab.cpp" break; case 461: /* type_specifier_nonarray: UIMAGE2D */ -#line 3122 "MachineIndependent/glslang.y" +#line 3126 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); } -#line 10091 "MachineIndependent/glslang_tab.cpp" +#line 10095 "MachineIndependent/glslang_tab.cpp" break; case 462: /* type_specifier_nonarray: IMAGE3D */ -#line 3127 "MachineIndependent/glslang.y" +#line 3131 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); } -#line 10101 "MachineIndependent/glslang_tab.cpp" +#line 10105 "MachineIndependent/glslang_tab.cpp" break; case 463: /* type_specifier_nonarray: F16IMAGE3D */ -#line 3132 "MachineIndependent/glslang.y" +#line 3136 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd3D); } -#line 10112 "MachineIndependent/glslang_tab.cpp" +#line 10116 "MachineIndependent/glslang_tab.cpp" break; case 464: /* type_specifier_nonarray: IIMAGE3D */ -#line 3138 "MachineIndependent/glslang.y" +#line 3142 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); } -#line 10122 "MachineIndependent/glslang_tab.cpp" +#line 10126 "MachineIndependent/glslang_tab.cpp" break; case 465: /* type_specifier_nonarray: UIMAGE3D */ -#line 3143 "MachineIndependent/glslang.y" +#line 3147 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); } -#line 10132 "MachineIndependent/glslang_tab.cpp" +#line 10136 "MachineIndependent/glslang_tab.cpp" break; case 466: /* type_specifier_nonarray: IMAGE2DRECT */ -#line 3148 "MachineIndependent/glslang.y" +#line 3152 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); } -#line 10142 "MachineIndependent/glslang_tab.cpp" +#line 10146 "MachineIndependent/glslang_tab.cpp" break; case 467: /* type_specifier_nonarray: F16IMAGE2DRECT */ -#line 3153 "MachineIndependent/glslang.y" +#line 3157 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdRect); } -#line 10153 "MachineIndependent/glslang_tab.cpp" +#line 10157 "MachineIndependent/glslang_tab.cpp" break; case 468: /* type_specifier_nonarray: IIMAGE2DRECT */ -#line 3159 "MachineIndependent/glslang.y" +#line 3163 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); } -#line 10163 "MachineIndependent/glslang_tab.cpp" +#line 10167 "MachineIndependent/glslang_tab.cpp" break; case 469: /* type_specifier_nonarray: UIMAGE2DRECT */ -#line 3164 "MachineIndependent/glslang.y" +#line 3168 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); } -#line 10173 "MachineIndependent/glslang_tab.cpp" +#line 10177 "MachineIndependent/glslang_tab.cpp" break; case 470: /* type_specifier_nonarray: IMAGECUBE */ -#line 3169 "MachineIndependent/glslang.y" +#line 3173 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); } -#line 10183 "MachineIndependent/glslang_tab.cpp" +#line 10187 "MachineIndependent/glslang_tab.cpp" break; case 471: /* type_specifier_nonarray: F16IMAGECUBE */ -#line 3174 "MachineIndependent/glslang.y" +#line 3178 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube); } -#line 10194 "MachineIndependent/glslang_tab.cpp" +#line 10198 "MachineIndependent/glslang_tab.cpp" break; case 472: /* type_specifier_nonarray: IIMAGECUBE */ -#line 3180 "MachineIndependent/glslang.y" +#line 3184 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); } -#line 10204 "MachineIndependent/glslang_tab.cpp" +#line 10208 "MachineIndependent/glslang_tab.cpp" break; case 473: /* type_specifier_nonarray: UIMAGECUBE */ -#line 3185 "MachineIndependent/glslang.y" +#line 3189 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); } -#line 10214 "MachineIndependent/glslang_tab.cpp" +#line 10218 "MachineIndependent/glslang_tab.cpp" break; case 474: /* type_specifier_nonarray: IMAGEBUFFER */ -#line 3190 "MachineIndependent/glslang.y" +#line 3194 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); } -#line 10224 "MachineIndependent/glslang_tab.cpp" +#line 10228 "MachineIndependent/glslang_tab.cpp" break; case 475: /* type_specifier_nonarray: F16IMAGEBUFFER */ -#line 3195 "MachineIndependent/glslang.y" +#line 3199 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdBuffer); } -#line 10235 "MachineIndependent/glslang_tab.cpp" +#line 10239 "MachineIndependent/glslang_tab.cpp" break; case 476: /* type_specifier_nonarray: IIMAGEBUFFER */ -#line 3201 "MachineIndependent/glslang.y" +#line 3205 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); } -#line 10245 "MachineIndependent/glslang_tab.cpp" +#line 10249 "MachineIndependent/glslang_tab.cpp" break; case 477: /* type_specifier_nonarray: UIMAGEBUFFER */ -#line 3206 "MachineIndependent/glslang.y" +#line 3210 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); } -#line 10255 "MachineIndependent/glslang_tab.cpp" +#line 10259 "MachineIndependent/glslang_tab.cpp" break; case 478: /* type_specifier_nonarray: IMAGE1DARRAY */ -#line 3211 "MachineIndependent/glslang.y" +#line 3215 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); } -#line 10265 "MachineIndependent/glslang_tab.cpp" +#line 10269 "MachineIndependent/glslang_tab.cpp" break; case 479: /* type_specifier_nonarray: F16IMAGE1DARRAY */ -#line 3216 "MachineIndependent/glslang.y" +#line 3220 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D, true); } -#line 10276 "MachineIndependent/glslang_tab.cpp" +#line 10280 "MachineIndependent/glslang_tab.cpp" break; case 480: /* type_specifier_nonarray: IIMAGE1DARRAY */ -#line 3222 "MachineIndependent/glslang.y" +#line 3226 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); } -#line 10286 "MachineIndependent/glslang_tab.cpp" +#line 10290 "MachineIndependent/glslang_tab.cpp" break; case 481: /* type_specifier_nonarray: UIMAGE1DARRAY */ -#line 3227 "MachineIndependent/glslang.y" +#line 3231 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); } -#line 10296 "MachineIndependent/glslang_tab.cpp" +#line 10300 "MachineIndependent/glslang_tab.cpp" break; case 482: /* type_specifier_nonarray: IMAGE2DARRAY */ -#line 3232 "MachineIndependent/glslang.y" +#line 3236 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); } -#line 10306 "MachineIndependent/glslang_tab.cpp" +#line 10310 "MachineIndependent/glslang_tab.cpp" break; case 483: /* type_specifier_nonarray: F16IMAGE2DARRAY */ -#line 3237 "MachineIndependent/glslang.y" +#line 3241 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true); } -#line 10317 "MachineIndependent/glslang_tab.cpp" +#line 10321 "MachineIndependent/glslang_tab.cpp" break; case 484: /* type_specifier_nonarray: IIMAGE2DARRAY */ -#line 3243 "MachineIndependent/glslang.y" +#line 3247 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); } -#line 10327 "MachineIndependent/glslang_tab.cpp" +#line 10331 "MachineIndependent/glslang_tab.cpp" break; case 485: /* type_specifier_nonarray: UIMAGE2DARRAY */ -#line 3248 "MachineIndependent/glslang.y" +#line 3252 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); } -#line 10337 "MachineIndependent/glslang_tab.cpp" +#line 10341 "MachineIndependent/glslang_tab.cpp" break; case 486: /* type_specifier_nonarray: IMAGECUBEARRAY */ -#line 3253 "MachineIndependent/glslang.y" +#line 3257 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); } -#line 10347 "MachineIndependent/glslang_tab.cpp" +#line 10351 "MachineIndependent/glslang_tab.cpp" break; case 487: /* type_specifier_nonarray: F16IMAGECUBEARRAY */ -#line 3258 "MachineIndependent/glslang.y" +#line 3262 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube, true); } -#line 10358 "MachineIndependent/glslang_tab.cpp" +#line 10362 "MachineIndependent/glslang_tab.cpp" break; case 488: /* type_specifier_nonarray: IIMAGECUBEARRAY */ -#line 3264 "MachineIndependent/glslang.y" +#line 3268 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); } -#line 10368 "MachineIndependent/glslang_tab.cpp" +#line 10372 "MachineIndependent/glslang_tab.cpp" break; case 489: /* type_specifier_nonarray: UIMAGECUBEARRAY */ -#line 3269 "MachineIndependent/glslang.y" +#line 3273 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); } -#line 10378 "MachineIndependent/glslang_tab.cpp" +#line 10382 "MachineIndependent/glslang_tab.cpp" break; case 490: /* type_specifier_nonarray: IMAGE2DMS */ -#line 3274 "MachineIndependent/glslang.y" +#line 3278 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); } -#line 10388 "MachineIndependent/glslang_tab.cpp" +#line 10392 "MachineIndependent/glslang_tab.cpp" break; case 491: /* type_specifier_nonarray: F16IMAGE2DMS */ -#line 3279 "MachineIndependent/glslang.y" +#line 3283 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, false, false, true); } -#line 10399 "MachineIndependent/glslang_tab.cpp" +#line 10403 "MachineIndependent/glslang_tab.cpp" break; case 492: /* type_specifier_nonarray: IIMAGE2DMS */ -#line 3285 "MachineIndependent/glslang.y" +#line 3289 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); } -#line 10409 "MachineIndependent/glslang_tab.cpp" +#line 10413 "MachineIndependent/glslang_tab.cpp" break; case 493: /* type_specifier_nonarray: UIMAGE2DMS */ -#line 3290 "MachineIndependent/glslang.y" +#line 3294 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); } -#line 10419 "MachineIndependent/glslang_tab.cpp" +#line 10423 "MachineIndependent/glslang_tab.cpp" break; case 494: /* type_specifier_nonarray: IMAGE2DMSARRAY */ -#line 3295 "MachineIndependent/glslang.y" +#line 3299 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); } -#line 10429 "MachineIndependent/glslang_tab.cpp" +#line 10433 "MachineIndependent/glslang_tab.cpp" break; case 495: /* type_specifier_nonarray: F16IMAGE2DMSARRAY */ -#line 3300 "MachineIndependent/glslang.y" +#line 3304 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true, false, true); } -#line 10440 "MachineIndependent/glslang_tab.cpp" +#line 10444 "MachineIndependent/glslang_tab.cpp" break; case 496: /* type_specifier_nonarray: IIMAGE2DMSARRAY */ -#line 3306 "MachineIndependent/glslang.y" +#line 3310 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); } -#line 10450 "MachineIndependent/glslang_tab.cpp" +#line 10454 "MachineIndependent/glslang_tab.cpp" break; case 497: /* type_specifier_nonarray: UIMAGE2DMSARRAY */ -#line 3311 "MachineIndependent/glslang.y" +#line 3315 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); } -#line 10460 "MachineIndependent/glslang_tab.cpp" +#line 10464 "MachineIndependent/glslang_tab.cpp" break; case 498: /* type_specifier_nonarray: I64IMAGE1D */ -#line 3316 "MachineIndependent/glslang.y" +#line 3320 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D); } -#line 10470 "MachineIndependent/glslang_tab.cpp" +#line 10474 "MachineIndependent/glslang_tab.cpp" break; case 499: /* type_specifier_nonarray: U64IMAGE1D */ -#line 3321 "MachineIndependent/glslang.y" +#line 3325 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D); } -#line 10480 "MachineIndependent/glslang_tab.cpp" +#line 10484 "MachineIndependent/glslang_tab.cpp" break; case 500: /* type_specifier_nonarray: I64IMAGE2D */ -#line 3326 "MachineIndependent/glslang.y" +#line 3330 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D); } -#line 10490 "MachineIndependent/glslang_tab.cpp" +#line 10494 "MachineIndependent/glslang_tab.cpp" break; case 501: /* type_specifier_nonarray: U64IMAGE2D */ -#line 3331 "MachineIndependent/glslang.y" +#line 3335 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D); } -#line 10500 "MachineIndependent/glslang_tab.cpp" +#line 10504 "MachineIndependent/glslang_tab.cpp" break; case 502: /* type_specifier_nonarray: I64IMAGE3D */ -#line 3336 "MachineIndependent/glslang.y" +#line 3340 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd3D); } -#line 10510 "MachineIndependent/glslang_tab.cpp" +#line 10514 "MachineIndependent/glslang_tab.cpp" break; case 503: /* type_specifier_nonarray: U64IMAGE3D */ -#line 3341 "MachineIndependent/glslang.y" +#line 3345 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd3D); } -#line 10520 "MachineIndependent/glslang_tab.cpp" +#line 10524 "MachineIndependent/glslang_tab.cpp" break; case 504: /* type_specifier_nonarray: I64IMAGE2DRECT */ -#line 3346 "MachineIndependent/glslang.y" +#line 3350 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdRect); } -#line 10530 "MachineIndependent/glslang_tab.cpp" +#line 10534 "MachineIndependent/glslang_tab.cpp" break; case 505: /* type_specifier_nonarray: U64IMAGE2DRECT */ -#line 3351 "MachineIndependent/glslang.y" +#line 3355 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdRect); } -#line 10540 "MachineIndependent/glslang_tab.cpp" +#line 10544 "MachineIndependent/glslang_tab.cpp" break; case 506: /* type_specifier_nonarray: I64IMAGECUBE */ -#line 3356 "MachineIndependent/glslang.y" +#line 3360 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube); } -#line 10550 "MachineIndependent/glslang_tab.cpp" +#line 10554 "MachineIndependent/glslang_tab.cpp" break; case 507: /* type_specifier_nonarray: U64IMAGECUBE */ -#line 3361 "MachineIndependent/glslang.y" +#line 3365 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube); } -#line 10560 "MachineIndependent/glslang_tab.cpp" +#line 10564 "MachineIndependent/glslang_tab.cpp" break; case 508: /* type_specifier_nonarray: I64IMAGEBUFFER */ -#line 3366 "MachineIndependent/glslang.y" +#line 3370 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdBuffer); } -#line 10570 "MachineIndependent/glslang_tab.cpp" +#line 10574 "MachineIndependent/glslang_tab.cpp" break; case 509: /* type_specifier_nonarray: U64IMAGEBUFFER */ -#line 3371 "MachineIndependent/glslang.y" +#line 3375 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdBuffer); } -#line 10580 "MachineIndependent/glslang_tab.cpp" +#line 10584 "MachineIndependent/glslang_tab.cpp" break; case 510: /* type_specifier_nonarray: I64IMAGE1DARRAY */ -#line 3376 "MachineIndependent/glslang.y" +#line 3380 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D, true); } -#line 10590 "MachineIndependent/glslang_tab.cpp" +#line 10594 "MachineIndependent/glslang_tab.cpp" break; case 511: /* type_specifier_nonarray: U64IMAGE1DARRAY */ -#line 3381 "MachineIndependent/glslang.y" +#line 3385 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D, true); } -#line 10600 "MachineIndependent/glslang_tab.cpp" +#line 10604 "MachineIndependent/glslang_tab.cpp" break; case 512: /* type_specifier_nonarray: I64IMAGE2DARRAY */ -#line 3386 "MachineIndependent/glslang.y" +#line 3390 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true); } -#line 10610 "MachineIndependent/glslang_tab.cpp" +#line 10614 "MachineIndependent/glslang_tab.cpp" break; case 513: /* type_specifier_nonarray: U64IMAGE2DARRAY */ -#line 3391 "MachineIndependent/glslang.y" +#line 3395 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true); } -#line 10620 "MachineIndependent/glslang_tab.cpp" +#line 10624 "MachineIndependent/glslang_tab.cpp" break; case 514: /* type_specifier_nonarray: I64IMAGECUBEARRAY */ -#line 3396 "MachineIndependent/glslang.y" +#line 3400 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube, true); } -#line 10630 "MachineIndependent/glslang_tab.cpp" +#line 10634 "MachineIndependent/glslang_tab.cpp" break; case 515: /* type_specifier_nonarray: U64IMAGECUBEARRAY */ -#line 3401 "MachineIndependent/glslang.y" +#line 3405 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube, true); } -#line 10640 "MachineIndependent/glslang_tab.cpp" +#line 10644 "MachineIndependent/glslang_tab.cpp" break; case 516: /* type_specifier_nonarray: I64IMAGE2DMS */ -#line 3406 "MachineIndependent/glslang.y" +#line 3410 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, false, false, true); } -#line 10650 "MachineIndependent/glslang_tab.cpp" +#line 10654 "MachineIndependent/glslang_tab.cpp" break; case 517: /* type_specifier_nonarray: U64IMAGE2DMS */ -#line 3411 "MachineIndependent/glslang.y" +#line 3415 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, false, false, true); } -#line 10660 "MachineIndependent/glslang_tab.cpp" +#line 10664 "MachineIndependent/glslang_tab.cpp" break; case 518: /* type_specifier_nonarray: I64IMAGE2DMSARRAY */ -#line 3416 "MachineIndependent/glslang.y" +#line 3420 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true, false, true); } -#line 10670 "MachineIndependent/glslang_tab.cpp" +#line 10674 "MachineIndependent/glslang_tab.cpp" break; case 519: /* type_specifier_nonarray: U64IMAGE2DMSARRAY */ -#line 3421 "MachineIndependent/glslang.y" +#line 3425 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true, false, true); } -#line 10680 "MachineIndependent/glslang_tab.cpp" +#line 10684 "MachineIndependent/glslang_tab.cpp" break; case 520: /* type_specifier_nonarray: SAMPLEREXTERNALOES */ -#line 3426 "MachineIndependent/glslang.y" +#line 3430 "MachineIndependent/glslang.y" { // GL_OES_EGL_image_external (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.external = true; } -#line 10691 "MachineIndependent/glslang_tab.cpp" +#line 10695 "MachineIndependent/glslang_tab.cpp" break; case 521: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */ -#line 3432 "MachineIndependent/glslang.y" +#line 3436 "MachineIndependent/glslang.y" { // GL_EXT_YUV_target (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.yuv = true; } -#line 10702 "MachineIndependent/glslang_tab.cpp" +#line 10706 "MachineIndependent/glslang_tab.cpp" break; case 522: /* type_specifier_nonarray: ATTACHMENTEXT */ -#line 3438 "MachineIndependent/glslang.y" +#line 3442 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setAttachmentEXT(EbtFloat); } -#line 10713 "MachineIndependent/glslang_tab.cpp" +#line 10717 "MachineIndependent/glslang_tab.cpp" break; case 523: /* type_specifier_nonarray: IATTACHMENTEXT */ -#line 3444 "MachineIndependent/glslang.y" +#line 3448 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setAttachmentEXT(EbtInt); } -#line 10724 "MachineIndependent/glslang_tab.cpp" +#line 10728 "MachineIndependent/glslang_tab.cpp" break; case 524: /* type_specifier_nonarray: UATTACHMENTEXT */ -#line 3450 "MachineIndependent/glslang.y" +#line 3454 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setAttachmentEXT(EbtUint); } -#line 10735 "MachineIndependent/glslang_tab.cpp" +#line 10739 "MachineIndependent/glslang_tab.cpp" break; case 525: /* type_specifier_nonarray: SUBPASSINPUT */ -#line 3456 "MachineIndependent/glslang.y" +#line 3460 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat); } -#line 10746 "MachineIndependent/glslang_tab.cpp" +#line 10750 "MachineIndependent/glslang_tab.cpp" break; case 526: /* type_specifier_nonarray: SUBPASSINPUTMS */ -#line 3462 "MachineIndependent/glslang.y" +#line 3466 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat, true); } -#line 10757 "MachineIndependent/glslang_tab.cpp" +#line 10761 "MachineIndependent/glslang_tab.cpp" break; case 527: /* type_specifier_nonarray: F16SUBPASSINPUT */ -#line 3468 "MachineIndependent/glslang.y" +#line 3472 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -10765,11 +10769,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16); } -#line 10769 "MachineIndependent/glslang_tab.cpp" +#line 10773 "MachineIndependent/glslang_tab.cpp" break; case 528: /* type_specifier_nonarray: F16SUBPASSINPUTMS */ -#line 3475 "MachineIndependent/glslang.y" +#line 3479 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -10777,55 +10781,55 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); } -#line 10781 "MachineIndependent/glslang_tab.cpp" +#line 10785 "MachineIndependent/glslang_tab.cpp" break; case 529: /* type_specifier_nonarray: ISUBPASSINPUT */ -#line 3482 "MachineIndependent/glslang.y" +#line 3486 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt); } -#line 10792 "MachineIndependent/glslang_tab.cpp" +#line 10796 "MachineIndependent/glslang_tab.cpp" break; case 530: /* type_specifier_nonarray: ISUBPASSINPUTMS */ -#line 3488 "MachineIndependent/glslang.y" +#line 3492 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt, true); } -#line 10803 "MachineIndependent/glslang_tab.cpp" +#line 10807 "MachineIndependent/glslang_tab.cpp" break; case 531: /* type_specifier_nonarray: USUBPASSINPUT */ -#line 3494 "MachineIndependent/glslang.y" +#line 3498 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint); } -#line 10814 "MachineIndependent/glslang_tab.cpp" +#line 10818 "MachineIndependent/glslang_tab.cpp" break; case 532: /* type_specifier_nonarray: USUBPASSINPUTMS */ -#line 3500 "MachineIndependent/glslang.y" +#line 3504 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint, true); } -#line 10825 "MachineIndependent/glslang_tab.cpp" +#line 10829 "MachineIndependent/glslang_tab.cpp" break; case 533: /* type_specifier_nonarray: FCOOPMATNV */ -#line 3506 "MachineIndependent/glslang.y" +#line 3510 "MachineIndependent/glslang.y" { parseContext.fcoopmatCheckNV((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); @@ -10833,11 +10837,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).coopmatNV = true; (yyval.interm.type).coopmatKHR = false; } -#line 10837 "MachineIndependent/glslang_tab.cpp" +#line 10841 "MachineIndependent/glslang_tab.cpp" break; case 534: /* type_specifier_nonarray: ICOOPMATNV */ -#line 3513 "MachineIndependent/glslang.y" +#line 3517 "MachineIndependent/glslang.y" { parseContext.intcoopmatCheckNV((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); @@ -10845,11 +10849,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).coopmatNV = true; (yyval.interm.type).coopmatKHR = false; } -#line 10849 "MachineIndependent/glslang_tab.cpp" +#line 10853 "MachineIndependent/glslang_tab.cpp" break; case 535: /* type_specifier_nonarray: UCOOPMATNV */ -#line 3520 "MachineIndependent/glslang.y" +#line 3524 "MachineIndependent/glslang.y" { parseContext.intcoopmatCheckNV((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); @@ -10857,11 +10861,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).coopmatNV = true; (yyval.interm.type).coopmatKHR = false; } -#line 10861 "MachineIndependent/glslang_tab.cpp" +#line 10865 "MachineIndependent/glslang_tab.cpp" break; case 536: /* type_specifier_nonarray: COOPMAT */ -#line 3527 "MachineIndependent/glslang.y" +#line 3531 "MachineIndependent/glslang.y" { parseContext.coopmatCheck((yyvsp[0].lex).loc, "coopmat", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); @@ -10869,39 +10873,39 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).coopmatNV = false; (yyval.interm.type).coopmatKHR = true; } -#line 10873 "MachineIndependent/glslang_tab.cpp" +#line 10877 "MachineIndependent/glslang_tab.cpp" break; case 537: /* type_specifier_nonarray: spirv_type_specifier */ -#line 3534 "MachineIndependent/glslang.y" +#line 3538 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 10882 "MachineIndependent/glslang_tab.cpp" +#line 10886 "MachineIndependent/glslang_tab.cpp" break; case 538: /* type_specifier_nonarray: HITOBJECTNV */ -#line 3538 "MachineIndependent/glslang.y" +#line 3542 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtHitObjectNV; } -#line 10891 "MachineIndependent/glslang_tab.cpp" +#line 10895 "MachineIndependent/glslang_tab.cpp" break; case 539: /* type_specifier_nonarray: struct_specifier */ -#line 3542 "MachineIndependent/glslang.y" +#line 3546 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); } -#line 10901 "MachineIndependent/glslang_tab.cpp" +#line 10905 "MachineIndependent/glslang_tab.cpp" break; case 540: /* type_specifier_nonarray: TYPE_NAME */ -#line 3547 "MachineIndependent/glslang.y" +#line 3551 "MachineIndependent/glslang.y" { // // This is for user defined type names. The lexical phase looked up the @@ -10915,47 +10919,47 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 10919 "MachineIndependent/glslang_tab.cpp" +#line 10923 "MachineIndependent/glslang_tab.cpp" break; case 541: /* precision_qualifier: HIGH_PRECISION */ -#line 3563 "MachineIndependent/glslang.y" +#line 3567 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); } -#line 10929 "MachineIndependent/glslang_tab.cpp" +#line 10933 "MachineIndependent/glslang_tab.cpp" break; case 542: /* precision_qualifier: MEDIUM_PRECISION */ -#line 3568 "MachineIndependent/glslang.y" +#line 3572 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); } -#line 10939 "MachineIndependent/glslang_tab.cpp" +#line 10943 "MachineIndependent/glslang_tab.cpp" break; case 543: /* precision_qualifier: LOW_PRECISION */ -#line 3573 "MachineIndependent/glslang.y" +#line 3577 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); } -#line 10949 "MachineIndependent/glslang_tab.cpp" +#line 10953 "MachineIndependent/glslang_tab.cpp" break; case 544: /* $@3: %empty */ -#line 3581 "MachineIndependent/glslang.y" +#line 3585 "MachineIndependent/glslang.y" { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 10955 "MachineIndependent/glslang_tab.cpp" +#line 10959 "MachineIndependent/glslang_tab.cpp" break; case 545: /* struct_specifier: STRUCT IDENTIFIER LEFT_BRACE $@3 struct_declaration_list RIGHT_BRACE */ -#line 3581 "MachineIndependent/glslang.y" +#line 3585 "MachineIndependent/glslang.y" { TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); @@ -10973,17 +10977,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 10977 "MachineIndependent/glslang_tab.cpp" +#line 10981 "MachineIndependent/glslang_tab.cpp" break; case 546: /* $@4: %empty */ -#line 3598 "MachineIndependent/glslang.y" +#line 3602 "MachineIndependent/glslang.y" { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 10983 "MachineIndependent/glslang_tab.cpp" +#line 10987 "MachineIndependent/glslang_tab.cpp" break; case 547: /* struct_specifier: STRUCT LEFT_BRACE $@4 struct_declaration_list RIGHT_BRACE */ -#line 3598 "MachineIndependent/glslang.y" +#line 3602 "MachineIndependent/glslang.y" { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); @@ -10991,19 +10995,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 10995 "MachineIndependent/glslang_tab.cpp" +#line 10999 "MachineIndependent/glslang_tab.cpp" break; case 548: /* struct_declaration_list: struct_declaration */ -#line 3608 "MachineIndependent/glslang.y" +#line 3612 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 11003 "MachineIndependent/glslang_tab.cpp" +#line 11007 "MachineIndependent/glslang_tab.cpp" break; case 549: /* struct_declaration_list: struct_declaration_list struct_declaration */ -#line 3611 "MachineIndependent/glslang.y" +#line 3615 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { @@ -11014,11 +11018,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 11018 "MachineIndependent/glslang_tab.cpp" +#line 11022 "MachineIndependent/glslang_tab.cpp" break; case 550: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */ -#line 3624 "MachineIndependent/glslang.y" +#line 3628 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -11041,11 +11045,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 11045 "MachineIndependent/glslang_tab.cpp" +#line 11049 "MachineIndependent/glslang_tab.cpp" break; case 551: /* struct_declaration: type_qualifier type_specifier struct_declarator_list SEMICOLON */ -#line 3646 "MachineIndependent/glslang.y" +#line 3650 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -11070,38 +11074,38 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 11074 "MachineIndependent/glslang_tab.cpp" +#line 11078 "MachineIndependent/glslang_tab.cpp" break; case 552: /* struct_declarator_list: struct_declarator */ -#line 3673 "MachineIndependent/glslang.y" +#line 3677 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 11083 "MachineIndependent/glslang_tab.cpp" +#line 11087 "MachineIndependent/glslang_tab.cpp" break; case 553: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ -#line 3677 "MachineIndependent/glslang.y" +#line 3681 "MachineIndependent/glslang.y" { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 11091 "MachineIndependent/glslang_tab.cpp" +#line 11095 "MachineIndependent/glslang_tab.cpp" break; case 554: /* struct_declarator: IDENTIFIER */ -#line 3683 "MachineIndependent/glslang.y" +#line 3687 "MachineIndependent/glslang.y" { (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); } -#line 11101 "MachineIndependent/glslang_tab.cpp" +#line 11105 "MachineIndependent/glslang_tab.cpp" break; case 555: /* struct_declarator: IDENTIFIER array_specifier */ -#line 3688 "MachineIndependent/glslang.y" +#line 3692 "MachineIndependent/glslang.y" { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); @@ -11110,246 +11114,246 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 11114 "MachineIndependent/glslang_tab.cpp" +#line 11118 "MachineIndependent/glslang_tab.cpp" break; case 556: /* initializer: assignment_expression */ -#line 3699 "MachineIndependent/glslang.y" +#line 3703 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 11122 "MachineIndependent/glslang_tab.cpp" +#line 11126 "MachineIndependent/glslang_tab.cpp" break; case 557: /* initializer: LEFT_BRACE initializer_list RIGHT_BRACE */ -#line 3702 "MachineIndependent/glslang.y" +#line 3706 "MachineIndependent/glslang.y" { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); } -#line 11133 "MachineIndependent/glslang_tab.cpp" +#line 11137 "MachineIndependent/glslang_tab.cpp" break; case 558: /* initializer: LEFT_BRACE initializer_list COMMA RIGHT_BRACE */ -#line 3708 "MachineIndependent/glslang.y" +#line 3712 "MachineIndependent/glslang.y" { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 11144 "MachineIndependent/glslang_tab.cpp" +#line 11148 "MachineIndependent/glslang_tab.cpp" break; case 559: /* initializer: LEFT_BRACE RIGHT_BRACE */ -#line 3714 "MachineIndependent/glslang.y" +#line 3718 "MachineIndependent/glslang.y" { const char* initFeature = "empty { } initializer"; parseContext.profileRequires((yyvsp[-1].lex).loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); parseContext.profileRequires((yyvsp[-1].lex).loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); (yyval.interm.intermTypedNode) = parseContext.intermediate.makeAggregate((yyvsp[-1].lex).loc); } -#line 11155 "MachineIndependent/glslang_tab.cpp" +#line 11159 "MachineIndependent/glslang_tab.cpp" break; case 560: /* initializer_list: initializer */ -#line 3723 "MachineIndependent/glslang.y" +#line 3727 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); } -#line 11163 "MachineIndependent/glslang_tab.cpp" +#line 11167 "MachineIndependent/glslang_tab.cpp" break; case 561: /* initializer_list: initializer_list COMMA initializer */ -#line 3726 "MachineIndependent/glslang.y" +#line 3730 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); } -#line 11171 "MachineIndependent/glslang_tab.cpp" +#line 11175 "MachineIndependent/glslang_tab.cpp" break; case 562: /* declaration_statement: declaration */ -#line 3732 "MachineIndependent/glslang.y" +#line 3736 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11177 "MachineIndependent/glslang_tab.cpp" +#line 11181 "MachineIndependent/glslang_tab.cpp" break; case 563: /* statement: compound_statement */ -#line 3736 "MachineIndependent/glslang.y" +#line 3740 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11183 "MachineIndependent/glslang_tab.cpp" +#line 11187 "MachineIndependent/glslang_tab.cpp" break; case 564: /* statement: simple_statement */ -#line 3737 "MachineIndependent/glslang.y" +#line 3741 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11189 "MachineIndependent/glslang_tab.cpp" +#line 11193 "MachineIndependent/glslang_tab.cpp" break; case 565: /* simple_statement: declaration_statement */ -#line 3743 "MachineIndependent/glslang.y" +#line 3747 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11195 "MachineIndependent/glslang_tab.cpp" +#line 11199 "MachineIndependent/glslang_tab.cpp" break; case 566: /* simple_statement: expression_statement */ -#line 3744 "MachineIndependent/glslang.y" +#line 3748 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11201 "MachineIndependent/glslang_tab.cpp" +#line 11205 "MachineIndependent/glslang_tab.cpp" break; case 567: /* simple_statement: selection_statement */ -#line 3745 "MachineIndependent/glslang.y" +#line 3749 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11207 "MachineIndependent/glslang_tab.cpp" +#line 11211 "MachineIndependent/glslang_tab.cpp" break; case 568: /* simple_statement: switch_statement */ -#line 3746 "MachineIndependent/glslang.y" +#line 3750 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11213 "MachineIndependent/glslang_tab.cpp" +#line 11217 "MachineIndependent/glslang_tab.cpp" break; case 569: /* simple_statement: case_label */ -#line 3747 "MachineIndependent/glslang.y" +#line 3751 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11219 "MachineIndependent/glslang_tab.cpp" +#line 11223 "MachineIndependent/glslang_tab.cpp" break; case 570: /* simple_statement: iteration_statement */ -#line 3748 "MachineIndependent/glslang.y" +#line 3752 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11225 "MachineIndependent/glslang_tab.cpp" +#line 11229 "MachineIndependent/glslang_tab.cpp" break; case 571: /* simple_statement: jump_statement */ -#line 3749 "MachineIndependent/glslang.y" +#line 3753 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11231 "MachineIndependent/glslang_tab.cpp" +#line 11235 "MachineIndependent/glslang_tab.cpp" break; case 572: /* simple_statement: demote_statement */ -#line 3750 "MachineIndependent/glslang.y" +#line 3754 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11237 "MachineIndependent/glslang_tab.cpp" +#line 11241 "MachineIndependent/glslang_tab.cpp" break; case 573: /* demote_statement: DEMOTE SEMICOLON */ -#line 3754 "MachineIndependent/glslang.y" +#line 3758 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "demote"); parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDemote, (yyvsp[-1].lex).loc); } -#line 11247 "MachineIndependent/glslang_tab.cpp" +#line 11251 "MachineIndependent/glslang_tab.cpp" break; case 574: /* compound_statement: LEFT_BRACE RIGHT_BRACE */ -#line 3762 "MachineIndependent/glslang.y" +#line 3766 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11253 "MachineIndependent/glslang_tab.cpp" +#line 11257 "MachineIndependent/glslang_tab.cpp" break; case 575: /* $@5: %empty */ -#line 3763 "MachineIndependent/glslang.y" +#line 3767 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 11262 "MachineIndependent/glslang_tab.cpp" +#line 11266 "MachineIndependent/glslang_tab.cpp" break; case 576: /* $@6: %empty */ -#line 3767 "MachineIndependent/glslang.y" +#line 3771 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 11271 "MachineIndependent/glslang_tab.cpp" +#line 11275 "MachineIndependent/glslang_tab.cpp" break; case 577: /* compound_statement: LEFT_BRACE $@5 statement_list $@6 RIGHT_BRACE */ -#line 3771 "MachineIndependent/glslang.y" +#line 3775 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(parseContext.intermediate.getDebugInfo() ? EOpScope : EOpSequence); (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); } -#line 11281 "MachineIndependent/glslang_tab.cpp" +#line 11285 "MachineIndependent/glslang_tab.cpp" break; case 578: /* statement_no_new_scope: compound_statement_no_new_scope */ -#line 3779 "MachineIndependent/glslang.y" +#line 3783 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11287 "MachineIndependent/glslang_tab.cpp" +#line 11291 "MachineIndependent/glslang_tab.cpp" break; case 579: /* statement_no_new_scope: simple_statement */ -#line 3780 "MachineIndependent/glslang.y" +#line 3784 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11293 "MachineIndependent/glslang_tab.cpp" +#line 11297 "MachineIndependent/glslang_tab.cpp" break; case 580: /* $@7: %empty */ -#line 3784 "MachineIndependent/glslang.y" +#line 3788 "MachineIndependent/glslang.y" { ++parseContext.controlFlowNestingLevel; } -#line 11301 "MachineIndependent/glslang_tab.cpp" +#line 11305 "MachineIndependent/glslang_tab.cpp" break; case 581: /* statement_scoped: $@7 compound_statement */ -#line 3787 "MachineIndependent/glslang.y" +#line 3791 "MachineIndependent/glslang.y" { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11310 "MachineIndependent/glslang_tab.cpp" +#line 11314 "MachineIndependent/glslang_tab.cpp" break; case 582: /* $@8: %empty */ -#line 3791 "MachineIndependent/glslang.y" +#line 3795 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11320 "MachineIndependent/glslang_tab.cpp" +#line 11324 "MachineIndependent/glslang_tab.cpp" break; case 583: /* statement_scoped: $@8 simple_statement */ -#line 3796 "MachineIndependent/glslang.y" +#line 3800 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11331 "MachineIndependent/glslang_tab.cpp" +#line 11335 "MachineIndependent/glslang_tab.cpp" break; case 584: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */ -#line 3805 "MachineIndependent/glslang.y" +#line 3809 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11339 "MachineIndependent/glslang_tab.cpp" +#line 11343 "MachineIndependent/glslang_tab.cpp" break; case 585: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */ -#line 3808 "MachineIndependent/glslang.y" +#line 3812 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); } -#line 11349 "MachineIndependent/glslang_tab.cpp" +#line 11353 "MachineIndependent/glslang_tab.cpp" break; case 586: /* statement_list: statement */ -#line 3816 "MachineIndependent/glslang.y" +#line 3820 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || @@ -11358,11 +11362,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 11362 "MachineIndependent/glslang_tab.cpp" +#line 11366 "MachineIndependent/glslang_tab.cpp" break; case 587: /* statement_list: statement_list statement */ -#line 3824 "MachineIndependent/glslang.y" +#line 3828 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { @@ -11371,77 +11375,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 11375 "MachineIndependent/glslang_tab.cpp" +#line 11379 "MachineIndependent/glslang_tab.cpp" break; case 588: /* expression_statement: SEMICOLON */ -#line 3835 "MachineIndependent/glslang.y" +#line 3839 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11381 "MachineIndependent/glslang_tab.cpp" +#line 11385 "MachineIndependent/glslang_tab.cpp" break; case 589: /* expression_statement: expression SEMICOLON */ -#line 3836 "MachineIndependent/glslang.y" +#line 3840 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 11387 "MachineIndependent/glslang_tab.cpp" +#line 11391 "MachineIndependent/glslang_tab.cpp" break; case 590: /* selection_statement: selection_statement_nonattributed */ -#line 3840 "MachineIndependent/glslang.y" +#line 3844 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11395 "MachineIndependent/glslang_tab.cpp" +#line 11399 "MachineIndependent/glslang_tab.cpp" break; case 591: /* selection_statement: attribute selection_statement_nonattributed */ -#line 3843 "MachineIndependent/glslang.y" +#line 3847 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11405 "MachineIndependent/glslang_tab.cpp" +#line 11409 "MachineIndependent/glslang_tab.cpp" break; case 592: /* selection_statement_nonattributed: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement */ -#line 3850 "MachineIndependent/glslang.y" +#line 3854 "MachineIndependent/glslang.y" { parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); } -#line 11414 "MachineIndependent/glslang_tab.cpp" +#line 11418 "MachineIndependent/glslang_tab.cpp" break; case 593: /* selection_rest_statement: statement_scoped ELSE statement_scoped */ -#line 3857 "MachineIndependent/glslang.y" +#line 3861 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 11423 "MachineIndependent/glslang_tab.cpp" +#line 11427 "MachineIndependent/glslang_tab.cpp" break; case 594: /* selection_rest_statement: statement_scoped */ -#line 3861 "MachineIndependent/glslang.y" +#line 3865 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 11432 "MachineIndependent/glslang_tab.cpp" +#line 11436 "MachineIndependent/glslang_tab.cpp" break; case 595: /* condition: expression */ -#line 3869 "MachineIndependent/glslang.y" +#line 3873 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); } -#line 11441 "MachineIndependent/glslang_tab.cpp" +#line 11445 "MachineIndependent/glslang_tab.cpp" break; case 596: /* condition: fully_specified_type IDENTIFIER EQUAL initializer */ -#line 3873 "MachineIndependent/glslang.y" +#line 3877 "MachineIndependent/glslang.y" { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -11452,29 +11456,29 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.intermTypedNode) = 0; } -#line 11456 "MachineIndependent/glslang_tab.cpp" +#line 11460 "MachineIndependent/glslang_tab.cpp" break; case 597: /* switch_statement: switch_statement_nonattributed */ -#line 3886 "MachineIndependent/glslang.y" +#line 3890 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11464 "MachineIndependent/glslang_tab.cpp" +#line 11468 "MachineIndependent/glslang_tab.cpp" break; case 598: /* switch_statement: attribute switch_statement_nonattributed */ -#line 3889 "MachineIndependent/glslang.y" +#line 3893 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11474 "MachineIndependent/glslang_tab.cpp" +#line 11478 "MachineIndependent/glslang_tab.cpp" break; case 599: /* $@9: %empty */ -#line 3896 "MachineIndependent/glslang.y" +#line 3900 "MachineIndependent/glslang.y" { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -11483,11 +11487,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 11487 "MachineIndependent/glslang_tab.cpp" +#line 11491 "MachineIndependent/glslang_tab.cpp" break; case 600: /* switch_statement_nonattributed: SWITCH LEFT_PAREN expression RIGHT_PAREN $@9 LEFT_BRACE switch_statement_list RIGHT_BRACE */ -#line 3904 "MachineIndependent/glslang.y" +#line 3908 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); delete parseContext.switchSequenceStack.back(); @@ -11497,27 +11501,27 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11501 "MachineIndependent/glslang_tab.cpp" +#line 11505 "MachineIndependent/glslang_tab.cpp" break; case 601: /* switch_statement_list: %empty */ -#line 3916 "MachineIndependent/glslang.y" +#line 3920 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11509 "MachineIndependent/glslang_tab.cpp" +#line 11513 "MachineIndependent/glslang_tab.cpp" break; case 602: /* switch_statement_list: statement_list */ -#line 3919 "MachineIndependent/glslang.y" +#line 3923 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11517 "MachineIndependent/glslang_tab.cpp" +#line 11521 "MachineIndependent/glslang_tab.cpp" break; case 603: /* case_label: CASE expression COLON */ -#line 3925 "MachineIndependent/glslang.y" +#line 3929 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -11530,11 +11534,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 11534 "MachineIndependent/glslang_tab.cpp" +#line 11538 "MachineIndependent/glslang_tab.cpp" break; case 604: /* case_label: DEFAULT COLON */ -#line 3937 "MachineIndependent/glslang.y" +#line 3941 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -11544,29 +11548,30 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 11548 "MachineIndependent/glslang_tab.cpp" +#line 11552 "MachineIndependent/glslang_tab.cpp" break; case 605: /* iteration_statement: iteration_statement_nonattributed */ -#line 3949 "MachineIndependent/glslang.y" +#line 3953 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11556 "MachineIndependent/glslang_tab.cpp" +#line 11560 "MachineIndependent/glslang_tab.cpp" break; case 606: /* iteration_statement: attribute iteration_statement_nonattributed */ -#line 3952 "MachineIndependent/glslang.y" +#line 3956 "MachineIndependent/glslang.y" { - parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); + const char * extensions[2] = { E_GL_EXT_control_flow_attributes, E_GL_EXT_control_flow_attributes2 }; + parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 2, extensions, "attribute"); parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11566 "MachineIndependent/glslang_tab.cpp" +#line 11571 "MachineIndependent/glslang_tab.cpp" break; case 607: /* $@10: %empty */ -#line 3959 "MachineIndependent/glslang.y" +#line 3964 "MachineIndependent/glslang.y" { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -11575,11 +11580,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11579 "MachineIndependent/glslang_tab.cpp" +#line 11584 "MachineIndependent/glslang_tab.cpp" break; case 608: /* iteration_statement_nonattributed: WHILE LEFT_PAREN $@10 condition RIGHT_PAREN statement_no_new_scope */ -#line 3967 "MachineIndependent/glslang.y" +#line 3972 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); @@ -11587,22 +11592,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11591 "MachineIndependent/glslang_tab.cpp" +#line 11596 "MachineIndependent/glslang_tab.cpp" break; case 609: /* $@11: %empty */ -#line 3974 "MachineIndependent/glslang.y" +#line 3979 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11602 "MachineIndependent/glslang_tab.cpp" +#line 11607 "MachineIndependent/glslang_tab.cpp" break; case 610: /* iteration_statement_nonattributed: DO $@11 statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON */ -#line 3980 "MachineIndependent/glslang.y" +#line 3985 "MachineIndependent/glslang.y" { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -11615,22 +11620,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11619 "MachineIndependent/glslang_tab.cpp" +#line 11624 "MachineIndependent/glslang_tab.cpp" break; case 611: /* $@12: %empty */ -#line 3992 "MachineIndependent/glslang.y" +#line 3997 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11630 "MachineIndependent/glslang_tab.cpp" +#line 11635 "MachineIndependent/glslang_tab.cpp" break; case 612: /* iteration_statement_nonattributed: FOR LEFT_PAREN $@12 for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope */ -#line 3998 "MachineIndependent/glslang.y" +#line 4003 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); @@ -11643,81 +11648,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11647 "MachineIndependent/glslang_tab.cpp" +#line 11652 "MachineIndependent/glslang_tab.cpp" break; case 613: /* for_init_statement: expression_statement */ -#line 4013 "MachineIndependent/glslang.y" +#line 4018 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11655 "MachineIndependent/glslang_tab.cpp" +#line 11660 "MachineIndependent/glslang_tab.cpp" break; case 614: /* for_init_statement: declaration_statement */ -#line 4016 "MachineIndependent/glslang.y" +#line 4021 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11663 "MachineIndependent/glslang_tab.cpp" +#line 11668 "MachineIndependent/glslang_tab.cpp" break; case 615: /* conditionopt: condition */ -#line 4022 "MachineIndependent/glslang.y" +#line 4027 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 11671 "MachineIndependent/glslang_tab.cpp" +#line 11676 "MachineIndependent/glslang_tab.cpp" break; case 616: /* conditionopt: %empty */ -#line 4025 "MachineIndependent/glslang.y" +#line 4030 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = 0; } -#line 11679 "MachineIndependent/glslang_tab.cpp" +#line 11684 "MachineIndependent/glslang_tab.cpp" break; case 617: /* for_rest_statement: conditionopt SEMICOLON */ -#line 4031 "MachineIndependent/glslang.y" +#line 4036 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 11688 "MachineIndependent/glslang_tab.cpp" +#line 11693 "MachineIndependent/glslang_tab.cpp" break; case 618: /* for_rest_statement: conditionopt SEMICOLON expression */ -#line 4035 "MachineIndependent/glslang.y" +#line 4040 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 11697 "MachineIndependent/glslang_tab.cpp" +#line 11702 "MachineIndependent/glslang_tab.cpp" break; case 619: /* jump_statement: CONTINUE SEMICOLON */ -#line 4042 "MachineIndependent/glslang.y" +#line 4047 "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 11707 "MachineIndependent/glslang_tab.cpp" +#line 11712 "MachineIndependent/glslang_tab.cpp" break; case 620: /* jump_statement: BREAK SEMICOLON */ -#line 4047 "MachineIndependent/glslang.y" +#line 4052 "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 11717 "MachineIndependent/glslang_tab.cpp" +#line 11722 "MachineIndependent/glslang_tab.cpp" break; case 621: /* jump_statement: RETURN SEMICOLON */ -#line 4052 "MachineIndependent/glslang.y" +#line 4057 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -11725,101 +11730,101 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 11729 "MachineIndependent/glslang_tab.cpp" +#line 11734 "MachineIndependent/glslang_tab.cpp" break; case 622: /* jump_statement: RETURN expression SEMICOLON */ -#line 4059 "MachineIndependent/glslang.y" +#line 4064 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 11737 "MachineIndependent/glslang_tab.cpp" +#line 11742 "MachineIndependent/glslang_tab.cpp" break; case 623: /* jump_statement: DISCARD SEMICOLON */ -#line 4062 "MachineIndependent/glslang.y" +#line 4067 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); } -#line 11746 "MachineIndependent/glslang_tab.cpp" +#line 11751 "MachineIndependent/glslang_tab.cpp" break; case 624: /* jump_statement: TERMINATE_INVOCATION SEMICOLON */ -#line 4066 "MachineIndependent/glslang.y" +#line 4071 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "terminateInvocation"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateInvocation, (yyvsp[-1].lex).loc); } -#line 11755 "MachineIndependent/glslang_tab.cpp" +#line 11760 "MachineIndependent/glslang_tab.cpp" break; case 625: /* jump_statement: TERMINATE_RAY SEMICOLON */ -#line 4070 "MachineIndependent/glslang.y" +#line 4075 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "terminateRayEXT"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateRayKHR, (yyvsp[-1].lex).loc); } -#line 11764 "MachineIndependent/glslang_tab.cpp" +#line 11769 "MachineIndependent/glslang_tab.cpp" break; case 626: /* jump_statement: IGNORE_INTERSECTION SEMICOLON */ -#line 4074 "MachineIndependent/glslang.y" +#line 4079 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "ignoreIntersectionEXT"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, (yyvsp[-1].lex).loc); } -#line 11773 "MachineIndependent/glslang_tab.cpp" +#line 11778 "MachineIndependent/glslang_tab.cpp" break; case 627: /* translation_unit: external_declaration */ -#line 4083 "MachineIndependent/glslang.y" +#line 4088 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 11782 "MachineIndependent/glslang_tab.cpp" +#line 11787 "MachineIndependent/glslang_tab.cpp" break; case 628: /* translation_unit: translation_unit external_declaration */ -#line 4087 "MachineIndependent/glslang.y" +#line 4092 "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 11793 "MachineIndependent/glslang_tab.cpp" +#line 11798 "MachineIndependent/glslang_tab.cpp" break; case 629: /* external_declaration: function_definition */ -#line 4096 "MachineIndependent/glslang.y" +#line 4101 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11801 "MachineIndependent/glslang_tab.cpp" +#line 11806 "MachineIndependent/glslang_tab.cpp" break; case 630: /* external_declaration: declaration */ -#line 4099 "MachineIndependent/glslang.y" +#line 4104 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11809 "MachineIndependent/glslang_tab.cpp" +#line 11814 "MachineIndependent/glslang_tab.cpp" break; case 631: /* external_declaration: SEMICOLON */ -#line 4102 "MachineIndependent/glslang.y" +#line 4107 "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 11819 "MachineIndependent/glslang_tab.cpp" +#line 11824 "MachineIndependent/glslang_tab.cpp" break; case 632: /* $@13: %empty */ -#line 4110 "MachineIndependent/glslang.y" +#line 4115 "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); @@ -11832,11 +11837,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); ++parseContext.statementNestingLevel; } } -#line 11836 "MachineIndependent/glslang_tab.cpp" +#line 11841 "MachineIndependent/glslang_tab.cpp" break; case 633: /* function_definition: function_prototype $@13 compound_statement_no_new_scope */ -#line 4122 "MachineIndependent/glslang.y" +#line 4127 "MachineIndependent/glslang.y" { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) @@ -11864,228 +11869,228 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; } } -#line 11868 "MachineIndependent/glslang_tab.cpp" +#line 11873 "MachineIndependent/glslang_tab.cpp" break; case 634: /* attribute: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET */ -#line 4152 "MachineIndependent/glslang.y" +#line 4157 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = (yyvsp[-2].interm.attributes); } -#line 11876 "MachineIndependent/glslang_tab.cpp" +#line 11881 "MachineIndependent/glslang_tab.cpp" break; case 635: /* attribute_list: single_attribute */ -#line 4157 "MachineIndependent/glslang.y" +#line 4162 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 11884 "MachineIndependent/glslang_tab.cpp" +#line 11889 "MachineIndependent/glslang_tab.cpp" break; case 636: /* attribute_list: attribute_list COMMA single_attribute */ -#line 4160 "MachineIndependent/glslang.y" +#line 4165 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 11892 "MachineIndependent/glslang_tab.cpp" +#line 11897 "MachineIndependent/glslang_tab.cpp" break; case 637: /* single_attribute: IDENTIFIER */ -#line 4165 "MachineIndependent/glslang.y" +#line 4170 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 11900 "MachineIndependent/glslang_tab.cpp" +#line 11905 "MachineIndependent/glslang_tab.cpp" break; case 638: /* single_attribute: IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN */ -#line 4168 "MachineIndependent/glslang.y" +#line 4173 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 11908 "MachineIndependent/glslang_tab.cpp" +#line 11913 "MachineIndependent/glslang_tab.cpp" break; case 639: /* spirv_requirements_list: spirv_requirements_parameter */ -#line 4173 "MachineIndependent/glslang.y" +#line 4178 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = (yyvsp[0].interm.spirvReq); } -#line 11916 "MachineIndependent/glslang_tab.cpp" +#line 11921 "MachineIndependent/glslang_tab.cpp" break; case 640: /* spirv_requirements_list: spirv_requirements_list COMMA spirv_requirements_parameter */ -#line 4176 "MachineIndependent/glslang.y" +#line 4181 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.mergeSpirvRequirements((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvReq), (yyvsp[0].interm.spirvReq)); } -#line 11924 "MachineIndependent/glslang_tab.cpp" +#line 11929 "MachineIndependent/glslang_tab.cpp" break; case 641: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET */ -#line 4181 "MachineIndependent/glslang.y" +#line 4186 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, (yyvsp[-1].interm.intermNode)->getAsAggregate(), nullptr); } -#line 11932 "MachineIndependent/glslang_tab.cpp" +#line 11937 "MachineIndependent/glslang_tab.cpp" break; case 642: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET */ -#line 4184 "MachineIndependent/glslang.y" +#line 4189 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, nullptr, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11940 "MachineIndependent/glslang_tab.cpp" +#line 11945 "MachineIndependent/glslang_tab.cpp" break; case 643: /* spirv_extension_list: STRING_LITERAL */ -#line 4189 "MachineIndependent/glslang.y" +#line 4194 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 11948 "MachineIndependent/glslang_tab.cpp" +#line 11953 "MachineIndependent/glslang_tab.cpp" break; case 644: /* spirv_extension_list: spirv_extension_list COMMA STRING_LITERAL */ -#line 4192 "MachineIndependent/glslang.y" +#line 4197 "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 11956 "MachineIndependent/glslang_tab.cpp" +#line 11961 "MachineIndependent/glslang_tab.cpp" break; case 645: /* spirv_capability_list: INTCONSTANT */ -#line 4197 "MachineIndependent/glslang.y" +#line 4202 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true)); } -#line 11964 "MachineIndependent/glslang_tab.cpp" +#line 11969 "MachineIndependent/glslang_tab.cpp" break; case 646: /* spirv_capability_list: spirv_capability_list COMMA INTCONSTANT */ -#line 4200 "MachineIndependent/glslang.y" +#line 4205 "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 11972 "MachineIndependent/glslang_tab.cpp" +#line 11977 "MachineIndependent/glslang_tab.cpp" break; case 647: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4205 "MachineIndependent/glslang.y" +#line 4210 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); (yyval.interm.intermNode) = 0; } -#line 11981 "MachineIndependent/glslang_tab.cpp" +#line 11986 "MachineIndependent/glslang_tab.cpp" break; case 648: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4209 "MachineIndependent/glslang.y" +#line 4214 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); (yyval.interm.intermNode) = 0; } -#line 11991 "MachineIndependent/glslang_tab.cpp" +#line 11996 "MachineIndependent/glslang_tab.cpp" break; case 649: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ -#line 4214 "MachineIndependent/glslang.y" +#line 4219 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 12000 "MachineIndependent/glslang_tab.cpp" +#line 12005 "MachineIndependent/glslang_tab.cpp" break; case 650: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ -#line 4218 "MachineIndependent/glslang.y" +#line 4223 "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 12010 "MachineIndependent/glslang_tab.cpp" +#line 12015 "MachineIndependent/glslang_tab.cpp" break; case 651: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ -#line 4223 "MachineIndependent/glslang.y" +#line 4228 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 12019 "MachineIndependent/glslang_tab.cpp" +#line 12024 "MachineIndependent/glslang_tab.cpp" break; case 652: /* 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 4227 "MachineIndependent/glslang.y" +#line 4232 "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 12029 "MachineIndependent/glslang_tab.cpp" +#line 12034 "MachineIndependent/glslang_tab.cpp" break; case 653: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter */ -#line 4234 "MachineIndependent/glslang.y" +#line 4239 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); } -#line 12037 "MachineIndependent/glslang_tab.cpp" +#line 12042 "MachineIndependent/glslang_tab.cpp" break; case 654: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter */ -#line 4237 "MachineIndependent/glslang.y" +#line 4242 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 12045 "MachineIndependent/glslang_tab.cpp" +#line 12050 "MachineIndependent/glslang_tab.cpp" break; case 655: /* spirv_execution_mode_parameter: FLOATCONSTANT */ -#line 4242 "MachineIndependent/glslang.y" +#line 4247 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 12053 "MachineIndependent/glslang_tab.cpp" +#line 12058 "MachineIndependent/glslang_tab.cpp" break; case 656: /* spirv_execution_mode_parameter: INTCONSTANT */ -#line 4245 "MachineIndependent/glslang.y" +#line 4250 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 12061 "MachineIndependent/glslang_tab.cpp" +#line 12066 "MachineIndependent/glslang_tab.cpp" break; case 657: /* spirv_execution_mode_parameter: UINTCONSTANT */ -#line 4248 "MachineIndependent/glslang.y" +#line 4253 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 12069 "MachineIndependent/glslang_tab.cpp" +#line 12074 "MachineIndependent/glslang_tab.cpp" break; case 658: /* spirv_execution_mode_parameter: BOOLCONSTANT */ -#line 4251 "MachineIndependent/glslang.y" +#line 4256 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 12077 "MachineIndependent/glslang_tab.cpp" +#line 12082 "MachineIndependent/glslang_tab.cpp" break; case 659: /* spirv_execution_mode_parameter: STRING_LITERAL */ -#line 4254 "MachineIndependent/glslang.y" +#line 4259 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); } -#line 12085 "MachineIndependent/glslang_tab.cpp" +#line 12090 "MachineIndependent/glslang_tab.cpp" break; case 660: /* spirv_execution_mode_id_parameter_list: constant_expression */ -#line 4259 "MachineIndependent/glslang.y" +#line 4264 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && @@ -12095,11 +12100,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 12099 "MachineIndependent/glslang_tab.cpp" +#line 12104 "MachineIndependent/glslang_tab.cpp" break; case 661: /* spirv_execution_mode_id_parameter_list: spirv_execution_mode_id_parameter_list COMMA constant_expression */ -#line 4268 "MachineIndependent/glslang.y" +#line 4273 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && @@ -12109,351 +12114,351 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); 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 12113 "MachineIndependent/glslang_tab.cpp" +#line 12118 "MachineIndependent/glslang_tab.cpp" break; case 662: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4279 "MachineIndependent/glslang.y" +#line 4284 "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 12123 "MachineIndependent/glslang_tab.cpp" +#line 12128 "MachineIndependent/glslang_tab.cpp" break; case 663: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4284 "MachineIndependent/glslang.y" +#line 4289 "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 12134 "MachineIndependent/glslang_tab.cpp" +#line 12139 "MachineIndependent/glslang_tab.cpp" break; case 664: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4292 "MachineIndependent/glslang.y" +#line 4297 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-3].lex).loc); (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i); } -#line 12143 "MachineIndependent/glslang_tab.cpp" +#line 12148 "MachineIndependent/glslang_tab.cpp" break; case 665: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4296 "MachineIndependent/glslang.y" +#line 4301 "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 12153 "MachineIndependent/glslang_tab.cpp" +#line 12158 "MachineIndependent/glslang_tab.cpp" break; case 666: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ -#line 4301 "MachineIndependent/glslang.y" +#line 4306 "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 12162 "MachineIndependent/glslang_tab.cpp" +#line 12167 "MachineIndependent/glslang_tab.cpp" break; case 667: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ -#line 4305 "MachineIndependent/glslang.y" +#line 4310 "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 12172 "MachineIndependent/glslang_tab.cpp" +#line 12177 "MachineIndependent/glslang_tab.cpp" break; case 668: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ -#line 4310 "MachineIndependent/glslang.y" +#line 4315 "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 12181 "MachineIndependent/glslang_tab.cpp" +#line 12186 "MachineIndependent/glslang_tab.cpp" break; case 669: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ -#line 4314 "MachineIndependent/glslang.y" +#line 4319 "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 12191 "MachineIndependent/glslang_tab.cpp" +#line 12196 "MachineIndependent/glslang_tab.cpp" break; case 670: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ -#line 4319 "MachineIndependent/glslang.y" +#line 4324 "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 12200 "MachineIndependent/glslang_tab.cpp" +#line 12205 "MachineIndependent/glslang_tab.cpp" break; case 671: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ -#line 4323 "MachineIndependent/glslang.y" +#line 4328 "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 12210 "MachineIndependent/glslang_tab.cpp" +#line 12215 "MachineIndependent/glslang_tab.cpp" break; case 672: /* spirv_decorate_parameter_list: spirv_decorate_parameter */ -#line 4330 "MachineIndependent/glslang.y" +#line 4335 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); } -#line 12218 "MachineIndependent/glslang_tab.cpp" +#line 12223 "MachineIndependent/glslang_tab.cpp" break; case 673: /* spirv_decorate_parameter_list: spirv_decorate_parameter_list COMMA spirv_decorate_parameter */ -#line 4333 "MachineIndependent/glslang.y" +#line 4338 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 12226 "MachineIndependent/glslang_tab.cpp" +#line 12231 "MachineIndependent/glslang_tab.cpp" break; case 674: /* spirv_decorate_parameter: FLOATCONSTANT */ -#line 4338 "MachineIndependent/glslang.y" +#line 4343 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 12234 "MachineIndependent/glslang_tab.cpp" +#line 12239 "MachineIndependent/glslang_tab.cpp" break; case 675: /* spirv_decorate_parameter: INTCONSTANT */ -#line 4341 "MachineIndependent/glslang.y" +#line 4346 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 12242 "MachineIndependent/glslang_tab.cpp" +#line 12247 "MachineIndependent/glslang_tab.cpp" break; case 676: /* spirv_decorate_parameter: UINTCONSTANT */ -#line 4344 "MachineIndependent/glslang.y" +#line 4349 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 12250 "MachineIndependent/glslang_tab.cpp" +#line 12255 "MachineIndependent/glslang_tab.cpp" break; case 677: /* spirv_decorate_parameter: BOOLCONSTANT */ -#line 4347 "MachineIndependent/glslang.y" +#line 4352 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 12258 "MachineIndependent/glslang_tab.cpp" +#line 12263 "MachineIndependent/glslang_tab.cpp" break; case 678: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter */ -#line 4352 "MachineIndependent/glslang.y" +#line 4357 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); } -#line 12266 "MachineIndependent/glslang_tab.cpp" +#line 12271 "MachineIndependent/glslang_tab.cpp" break; case 679: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter */ -#line 4355 "MachineIndependent/glslang.y" +#line 4360 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 12274 "MachineIndependent/glslang_tab.cpp" +#line 12279 "MachineIndependent/glslang_tab.cpp" break; case 680: /* spirv_decorate_id_parameter: variable_identifier */ -#line 4360 "MachineIndependent/glslang.y" +#line 4365 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermTypedNode)->getAsConstantUnion() || (yyvsp[0].interm.intermTypedNode)->getAsSymbolNode()) (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode); else parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "only allow constants or variables which are not elements of a composite", "", ""); } -#line 12285 "MachineIndependent/glslang_tab.cpp" +#line 12290 "MachineIndependent/glslang_tab.cpp" break; case 681: /* spirv_decorate_id_parameter: FLOATCONSTANT */ -#line 4366 "MachineIndependent/glslang.y" +#line 4371 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 12293 "MachineIndependent/glslang_tab.cpp" +#line 12298 "MachineIndependent/glslang_tab.cpp" break; case 682: /* spirv_decorate_id_parameter: INTCONSTANT */ -#line 4369 "MachineIndependent/glslang.y" +#line 4374 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 12301 "MachineIndependent/glslang_tab.cpp" +#line 12306 "MachineIndependent/glslang_tab.cpp" break; case 683: /* spirv_decorate_id_parameter: UINTCONSTANT */ -#line 4372 "MachineIndependent/glslang.y" +#line 4377 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 12309 "MachineIndependent/glslang_tab.cpp" +#line 12314 "MachineIndependent/glslang_tab.cpp" break; case 684: /* spirv_decorate_id_parameter: BOOLCONSTANT */ -#line 4375 "MachineIndependent/glslang.y" +#line 4380 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 12317 "MachineIndependent/glslang_tab.cpp" +#line 12322 "MachineIndependent/glslang_tab.cpp" break; case 685: /* spirv_decorate_string_parameter_list: STRING_LITERAL */ -#line 4380 "MachineIndependent/glslang.y" +#line 4385 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate( parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 12326 "MachineIndependent/glslang_tab.cpp" +#line 12331 "MachineIndependent/glslang_tab.cpp" break; case 686: /* spirv_decorate_string_parameter_list: spirv_decorate_string_parameter_list COMMA STRING_LITERAL */ -#line 4384 "MachineIndependent/glslang.y" +#line 4389 "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 12334 "MachineIndependent/glslang_tab.cpp" +#line 12339 "MachineIndependent/glslang_tab.cpp" break; case 687: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ -#line 4389 "MachineIndependent/glslang.y" +#line 4394 "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 12343 "MachineIndependent/glslang_tab.cpp" +#line 12348 "MachineIndependent/glslang_tab.cpp" break; case 688: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ -#line 4393 "MachineIndependent/glslang.y" +#line 4398 "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 12353 "MachineIndependent/glslang_tab.cpp" +#line 12358 "MachineIndependent/glslang_tab.cpp" break; case 689: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4398 "MachineIndependent/glslang.y" +#line 4403 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-3].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst)); } -#line 12362 "MachineIndependent/glslang_tab.cpp" +#line 12367 "MachineIndependent/glslang_tab.cpp" break; case 690: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4402 "MachineIndependent/glslang.y" +#line 4407 "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 12372 "MachineIndependent/glslang_tab.cpp" +#line 12377 "MachineIndependent/glslang_tab.cpp" break; case 691: /* spirv_type_parameter_list: spirv_type_parameter */ -#line 4409 "MachineIndependent/glslang.y" +#line 4414 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = (yyvsp[0].interm.spirvTypeParams); } -#line 12380 "MachineIndependent/glslang_tab.cpp" +#line 12385 "MachineIndependent/glslang_tab.cpp" break; case 692: /* spirv_type_parameter_list: spirv_type_parameter_list COMMA spirv_type_parameter */ -#line 4412 "MachineIndependent/glslang.y" +#line 4417 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = parseContext.mergeSpirvTypeParameters((yyvsp[-2].interm.spirvTypeParams), (yyvsp[0].interm.spirvTypeParams)); } -#line 12388 "MachineIndependent/glslang_tab.cpp" +#line 12393 "MachineIndependent/glslang_tab.cpp" break; case 693: /* spirv_type_parameter: constant_expression */ -#line 4417 "MachineIndependent/glslang.y" +#line 4422 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)->getAsConstantUnion()); } -#line 12396 "MachineIndependent/glslang_tab.cpp" +#line 12401 "MachineIndependent/glslang_tab.cpp" break; case 694: /* spirv_type_parameter: type_specifier_nonarray */ -#line 4420 "MachineIndependent/glslang.y" +#line 4425 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 12404 "MachineIndependent/glslang_tab.cpp" +#line 12409 "MachineIndependent/glslang_tab.cpp" break; case 695: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4425 "MachineIndependent/glslang.y" +#line 4430 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); } -#line 12412 "MachineIndependent/glslang_tab.cpp" +#line 12417 "MachineIndependent/glslang_tab.cpp" break; case 696: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4428 "MachineIndependent/glslang.y" +#line 4433 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); } -#line 12421 "MachineIndependent/glslang_tab.cpp" +#line 12426 "MachineIndependent/glslang_tab.cpp" break; case 697: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_id */ -#line 4434 "MachineIndependent/glslang.y" +#line 4439 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = (yyvsp[0].interm.spirvInst); } -#line 12429 "MachineIndependent/glslang_tab.cpp" +#line 12434 "MachineIndependent/glslang_tab.cpp" break; case 698: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id */ -#line 4437 "MachineIndependent/glslang.y" +#line 4442 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.mergeSpirvInstruction((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvInst), (yyvsp[0].interm.spirvInst)); } -#line 12437 "MachineIndependent/glslang_tab.cpp" +#line 12442 "MachineIndependent/glslang_tab.cpp" break; case 699: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL STRING_LITERAL */ -#line 4442 "MachineIndependent/glslang.y" +#line 4447 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, *(yyvsp[0].lex).string); } -#line 12445 "MachineIndependent/glslang_tab.cpp" +#line 12450 "MachineIndependent/glslang_tab.cpp" break; case 700: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */ -#line 4445 "MachineIndependent/glslang.y" +#line 4450 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[0].lex).i); } -#line 12453 "MachineIndependent/glslang_tab.cpp" +#line 12458 "MachineIndependent/glslang_tab.cpp" break; -#line 12457 "MachineIndependent/glslang_tab.cpp" +#line 12462 "MachineIndependent/glslang_tab.cpp" default: break; } @@ -12677,5 +12682,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 4449 "MachineIndependent/glslang.y" +#line 4454 "MachineIndependent/glslang.y" diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp index 1bd6678..62e2442 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -1689,7 +1689,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // First range: TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation); TRange componentRange(0, 3); - TIoRange range(locationRange, componentRange, type.getBasicType(), 0); + TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat); // check for collisions collision = checkLocationRange(set, range, type, typeCollision); @@ -1699,7 +1699,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // Second range: TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1); TRange componentRange2(0, 1); - TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0); + TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat); // check for collisions collision = checkLocationRange(set, range2, type, typeCollision); @@ -1725,7 +1725,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ TBasicType basicTy = type.getBasicType(); if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT()) basicTy = type.getSampler().type; - TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0); + TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat); // check for collisions, except for vertex inputs on desktop targeting OpenGL if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) @@ -1748,7 +1748,11 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp if (range.overlap(usedIo[set][r])) { // there is a collision; pick one return std::max(range.location.start, usedIo[set][r].location.start); - } else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) { + } else if (range.location.overlap(usedIo[set][r].location) && + (type.getBasicType() != usedIo[set][r].basicType || + type.getQualifier().centroid != usedIo[set][r].centroid || + type.getQualifier().smooth != usedIo[set][r].smooth || + type.getQualifier().flat != usedIo[set][r].flat)) { // aliased-type mismatch typeCollision = true; return std::max(range.location.start, usedIo[set][r].location.start); @@ -2217,9 +2221,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T } // To aid the basic HLSL rule about crossing vec4 boundaries. -bool TIntermediate::improperStraddle(const TType& type, int size, int offset) +bool TIntermediate::improperStraddle(const TType& type, int size, int offset, bool vectorLike) { - if (! type.isVector() || type.isArray()) + if (! vectorLike || type.isArray()) return false; return size <= 16 ? offset / 16 != (offset + size - 1) / 16 diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h index db0367f..2a24cda 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/localintermediate.h @@ -123,8 +123,10 @@ struct TRange { // within the same location range, component range, and index value. Locations don't alias unless // all other dimensions of their range overlap. struct TIoRange { - TIoRange(TRange location, TRange component, TBasicType basicType, int index) - : location(location), component(component), basicType(basicType), index(index) { } + TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat) + : location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat) + { + } bool overlap(const TIoRange& rhs) const { return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index; @@ -133,6 +135,9 @@ struct TIoRange { TRange component; TBasicType basicType; int index; + bool centroid; + bool smooth; + bool flat; }; // An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying @@ -724,6 +729,11 @@ class TIntermediate { usePhysicalStorageBuffer = true; } bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; } + void setReplicatedComposites() + { + useReplicatedComposites = true; + } + bool usingReplicatedComposites() const { return useReplicatedComposites; } void setUseVariablePointers() { useVariablePointers = true; @@ -1057,7 +1067,7 @@ class TIntermediate { static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor); static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); - static bool improperStraddle(const TType& type, int size, int offset); + static bool improperStraddle(const TType& type, int size, int offset, bool vectorLike); static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize); static int getOffset(const TType& type, int index); static int getBlockSize(const TType& blockType); @@ -1237,6 +1247,7 @@ class TIntermediate { bool subgroupUniformControlFlow; bool maximallyReconverges; bool usePhysicalStorageBuffer; + bool useReplicatedComposites { false }; TSpirvRequirement* spirvRequirement; TSpirvExecutionMode* spirvExecutionMode; @@ -1251,7 +1262,7 @@ class TIntermediate { std::unordered_set usedConstantId; // specialization constant ids used std::vector usedAtomics; // sets of bindings used by atomic counters - std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers + std::vector usedIo[5]; // sets of used locations, one for each of in, out, uniform, and buffers std::vector usedIoRT[4]; // sets of used location, one for rayPayload/rayPayloadIN, // one for callableData/callableDataIn, one for hitObjectAttributeNV and // one for shaderrecordhitobjectNV diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/parseVersions.h b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/parseVersions.h index 63841c4..5c77e42 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/parseVersions.h +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/parseVersions.h @@ -83,6 +83,11 @@ class TParseVersions { const char* featureDesc); virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc); + template + constexpr void ppRequireExtensions(const TSourceLoc& loc, Container extensions, const char* featureDesc) { + ppRequireExtensions(loc, static_cast(extensions.size()), extensions.data(), featureDesc); + } + virtual TExtensionBehavior getExtensionBehavior(const char*); virtual bool extensionTurnedOn(const char* const extension); virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]); diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp index 16b9d24..5f18c4e 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -973,7 +973,8 @@ int TPpContext::readCPPline(TPpToken* ppToken) break; case PpAtomInclude: if(!parseContext.isReadingHLSL()) { - parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); + const std::array exts = { E_GL_GOOGLE_include_directive, E_GL_ARB_shading_language_include }; + parseContext.ppRequireExtensions(ppToken->loc, exts, "#include"); } token = CPPinclude(ppToken); break; diff --git a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp index 34dec20..49dafa5 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/libs/bgfx/3rdparty/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -220,7 +220,9 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { - exponent = exponent * 10 + (ch - '0'); + if (exponent < 500) { + exponent = exponent * 10 + (ch - '0'); + } saveName(ch); ch = getChar(); } diff --git a/libs/bgfx/3rdparty/glslang/glslang/Public/ShaderLang.h b/libs/bgfx/3rdparty/glslang/glslang/Public/ShaderLang.h index e0ec47f..b71b147 100644 --- a/libs/bgfx/3rdparty/glslang/glslang/Public/ShaderLang.h +++ b/libs/bgfx/3rdparty/glslang/glslang/Public/ShaderLang.h @@ -252,23 +252,24 @@ typedef enum { // Message choices for what errors and warnings are given. // enum EShMessages : unsigned { - EShMsgDefault = 0, // default is to give all required errors and extra warnings - EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input - EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification - EShMsgAST = (1 << 2), // print the AST intermediate representation - EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation - EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V - EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor - EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics - EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit - EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions - EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules - EShMsgDebugInfo = (1 << 10), // save debug information - EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL - EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages - EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) - EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table - EShMsgEnhanced = (1 << 15), // enhanced message readability + EShMsgDefault = 0, // default is to give all required errors and extra warnings + EShMsgRelaxedErrors = (1 << 0), // be liberal in accepting input + EShMsgSuppressWarnings = (1 << 1), // suppress all warnings, except those required by the specification + EShMsgAST = (1 << 2), // print the AST intermediate representation + EShMsgSpvRules = (1 << 3), // issue messages for SPIR-V generation + EShMsgVulkanRules = (1 << 4), // issue messages for Vulkan-requirements of GLSL for SPIR-V + EShMsgOnlyPreprocessor = (1 << 5), // only print out errors produced by the preprocessor + EShMsgReadHlsl = (1 << 6), // use HLSL parsing rules and semantics + EShMsgCascadingErrors = (1 << 7), // get cascading errors; risks error-recovery issues, instead of an early exit + EShMsgKeepUncalled = (1 << 8), // for testing, don't eliminate uncalled functions + EShMsgHlslOffsets = (1 << 9), // allow block offsets to follow HLSL rules instead of GLSL rules + EShMsgDebugInfo = (1 << 10), // save debug information + EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL + EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages + EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) + EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + EShMsgEnhanced = (1 << 15), // enhanced message readability + EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages LAST_ELEMENT_MARKER(EShMsgCount), }; @@ -335,7 +336,8 @@ GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[], int, // debugOptions unused int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader bool forwardCompatible = false, // give errors for use of deprecated features - EShMessages messages = EShMsgDefault // warnings and errors + EShMessages messages = EShMsgDefault, // warnings and errors + const char* fileName = nullptr ); GLSLANG_EXPORT int ShLinkExt( @@ -743,6 +745,8 @@ class TObjectReflection { GLSLANG_EXPORT void dump() const; static TObjectReflection badReflection() { return TObjectReflection(); } + GLSLANG_EXPORT unsigned int layoutLocation() const; + std::string name; int offset; int glDefineType; diff --git a/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h b/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h index 7e6b040..8453843 100644 --- a/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h +++ b/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_core.h @@ -69,7 +69,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 278 +#define VK_HEADER_VERSION 288 // Complete version of this file #define VK_HEADER_VERSION_COMPLETE VK_MAKE_API_VERSION(0, 1, 3, VK_HEADER_VERSION) @@ -1046,6 +1046,8 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_SPARSE_ADDRESS_SPACE_PROPERTIES_NV = 1000492001, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT = 1000351000, VK_STRUCTURE_TYPE_MUTABLE_DESCRIPTOR_TYPE_CREATE_INFO_EXT = 1000351002, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_FEATURES_EXT = 1000495000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_VERTEX_ATTRIBUTES_PROPERTIES_EXT = 1000495001, VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT = 1000496000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_FEATURES_ARM = 1000497000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_BUILTINS_PROPERTIES_ARM = 1000497001, @@ -1109,7 +1111,14 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_SET_DESCRIPTOR_BUFFER_OFFSETS_INFO_EXT = 1000545007, VK_STRUCTURE_TYPE_BIND_DESCRIPTOR_BUFFER_EMBEDDED_SAMPLERS_INFO_EXT = 1000545008, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_POOL_OVERALLOCATION_FEATURES_NV = 1000546000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAW_ACCESS_CHAINS_FEATURES_NV = 1000555000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_RELAXED_EXTENDED_INSTRUCTION_FEATURES_KHR = 1000558000, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT16_VECTOR_FEATURES_NV = 1000563000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_REPLICATED_COMPOSITES_FEATURES_EXT = 1000564000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_VALIDATION_FEATURES_NV = 1000568000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_FEATURES_MESA = 1000575000, + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ALIGNMENT_CONTROL_PROPERTIES_MESA = 1000575001, + VK_STRUCTURE_TYPE_IMAGE_ALIGNMENT_CONTROL_CREATE_INFO_MESA = 1000575002, 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, @@ -1402,6 +1411,7 @@ typedef enum VkObjectType { } VkObjectType; typedef enum VkVendorId { + VK_VENDOR_ID_KHRONOS = 0x10000, VK_VENDOR_ID_VIV = 0x10001, VK_VENDOR_ID_VSI = 0x10002, VK_VENDOR_ID_KAZAN = 0x10003, @@ -1674,7 +1684,7 @@ typedef enum VkFormat { VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG = 1000054005, VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG = 1000054006, VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG = 1000054007, - VK_FORMAT_R16G16_S10_5_NV = 1000464000, + VK_FORMAT_R16G16_SFIXED5_NV = 1000464000, VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = 1000470000, VK_FORMAT_A8_UNORM_KHR = 1000470001, VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT = VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK, @@ -1731,6 +1741,7 @@ typedef enum VkFormat { VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM, VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT = VK_FORMAT_A4R4G4B4_UNORM_PACK16, VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT = VK_FORMAT_A4B4G4R4_UNORM_PACK16, + VK_FORMAT_R16G16_S10_5_NV = VK_FORMAT_R16G16_SFIXED5_NV, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF } VkFormat; @@ -5782,7 +5793,8 @@ typedef enum VkDriverId { VK_DRIVER_ID_MESA_DOZEN = 23, VK_DRIVER_ID_MESA_NVK = 24, VK_DRIVER_ID_IMAGINATION_OPEN_SOURCE_MESA = 25, - VK_DRIVER_ID_MESA_AGXV = 26, + VK_DRIVER_ID_MESA_HONEYKRISP = 26, + VK_DRIVER_ID_RESERVED_27 = 27, 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, @@ -10257,7 +10269,7 @@ typedef struct VkRenderingInputAttachmentIndexInfoKHR { } VkRenderingInputAttachmentIndexInfoKHR; typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingAttachmentLocationsKHR)(VkCommandBuffer commandBuffer, const VkRenderingAttachmentLocationInfoKHR* pLocationInfo); -typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingInputAttachmentIndicesKHR)(VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfoKHR* pLocationInfo); +typedef void (VKAPI_PTR *PFN_vkCmdSetRenderingInputAttachmentIndicesKHR)(VkCommandBuffer commandBuffer, const VkRenderingInputAttachmentIndexInfoKHR* pInputAttachmentIndexInfo); #ifndef VK_NO_PROTOTYPES VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingAttachmentLocationsKHR( @@ -10266,7 +10278,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingAttachmentLocationsKHR( VKAPI_ATTR void VKAPI_CALL vkCmdSetRenderingInputAttachmentIndicesKHR( VkCommandBuffer commandBuffer, - const VkRenderingInputAttachmentIndexInfoKHR* pLocationInfo); + const VkRenderingInputAttachmentIndexInfoKHR* pInputAttachmentIndexInfo); #endif @@ -11107,6 +11119,7 @@ typedef VkFlags64 VkPipelineCreateFlagBits2KHR; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISABLE_OPTIMIZATION_BIT_KHR = 0x00000001ULL; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_ALLOW_DERIVATIVES_BIT_KHR = 0x00000002ULL; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DERIVATIVE_BIT_KHR = 0x00000004ULL; +static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_ENABLE_LEGACY_DITHERING_BIT_EXT = 0x400000000ULL; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_VIEW_INDEX_FROM_DEVICE_INDEX_BIT_KHR = 0x00000008ULL; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT_KHR = 0x00000010ULL; static const VkPipelineCreateFlagBits2KHR VK_PIPELINE_CREATE_2_DEFER_COMPILE_BIT_NV = 0x00000020ULL; @@ -11157,12 +11170,8 @@ static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_BUFF static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_TRANSFORM_FEEDBACK_COUNTER_BUFFER_BIT_EXT = 0x00001000ULL; static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_SRC_BIT_KHR = 0x00002000ULL; static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_DECODE_DST_BIT_KHR = 0x00004000ULL; -#ifdef VK_ENABLE_BETA_EXTENSIONS static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_DST_BIT_KHR = 0x00008000ULL; -#endif -#ifdef VK_ENABLE_BETA_EXTENSIONS static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_VIDEO_ENCODE_SRC_BIT_KHR = 0x00010000ULL; -#endif static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR = 0x00020000ULL; static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR = 0x00080000ULL; static const VkBufferUsageFlagBits2KHR VK_BUFFER_USAGE_2_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR = 0x00100000ULL; @@ -11701,6 +11710,18 @@ VKAPI_ATTR void VKAPI_CALL vkCmdBindDescriptorBufferEmbeddedSamplers2EXT( #endif +// VK_KHR_shader_relaxed_extended_instruction is a preprocessor guard. Do not pass it to API calls. +#define VK_KHR_shader_relaxed_extended_instruction 1 +#define VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_SPEC_VERSION 1 +#define VK_KHR_SHADER_RELAXED_EXTENDED_INSTRUCTION_EXTENSION_NAME "VK_KHR_shader_relaxed_extended_instruction" +typedef struct VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR { + VkStructureType sType; + void* pNext; + VkBool32 shaderRelaxedExtendedInstruction; +} VkPhysicalDeviceShaderRelaxedExtendedInstructionFeaturesKHR; + + + // VK_EXT_debug_report is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_debug_report 1 VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT) @@ -18504,7 +18525,7 @@ VKAPI_ATTR void VKAPI_CALL vkCmdOpticalFlowExecuteNV( // VK_EXT_legacy_dithering is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_legacy_dithering 1 -#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 1 +#define VK_EXT_LEGACY_DITHERING_SPEC_VERSION 2 #define VK_EXT_LEGACY_DITHERING_EXTENSION_NAME "VK_EXT_legacy_dithering" typedef struct VkPhysicalDeviceLegacyDitheringFeaturesEXT { VkStructureType sType; @@ -18729,6 +18750,24 @@ typedef struct VkPhysicalDeviceExtendedSparseAddressSpacePropertiesNV { #define VK_EXT_MUTABLE_DESCRIPTOR_TYPE_EXTENSION_NAME "VK_EXT_mutable_descriptor_type" +// VK_EXT_legacy_vertex_attributes is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_legacy_vertex_attributes 1 +#define VK_EXT_LEGACY_VERTEX_ATTRIBUTES_SPEC_VERSION 1 +#define VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME "VK_EXT_legacy_vertex_attributes" +typedef struct VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 legacyVertexAttributes; +} VkPhysicalDeviceLegacyVertexAttributesFeaturesEXT; + +typedef struct VkPhysicalDeviceLegacyVertexAttributesPropertiesEXT { + VkStructureType sType; + void* pNext; + VkBool32 nativeUnalignedPerformance; +} VkPhysicalDeviceLegacyVertexAttributesPropertiesEXT; + + + // VK_EXT_layer_settings is a preprocessor guard. Do not pass it to API calls. #define VK_EXT_layer_settings 1 #define VK_EXT_LAYER_SETTINGS_SPEC_VERSION 2 @@ -19113,6 +19152,18 @@ typedef struct VkPhysicalDeviceDescriptorPoolOverallocationFeaturesNV { +// VK_NV_raw_access_chains is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_raw_access_chains 1 +#define VK_NV_RAW_ACCESS_CHAINS_SPEC_VERSION 1 +#define VK_NV_RAW_ACCESS_CHAINS_EXTENSION_NAME "VK_NV_raw_access_chains" +typedef struct VkPhysicalDeviceRawAccessChainsFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 shaderRawAccessChains; +} VkPhysicalDeviceRawAccessChainsFeaturesNV; + + + // VK_NV_shader_atomic_float16_vector is a preprocessor guard. Do not pass it to API calls. #define VK_NV_shader_atomic_float16_vector 1 #define VK_NV_SHADER_ATOMIC_FLOAT16_VECTOR_SPEC_VERSION 1 @@ -19125,6 +19176,54 @@ typedef struct VkPhysicalDeviceShaderAtomicFloat16VectorFeaturesNV { +// VK_EXT_shader_replicated_composites is a preprocessor guard. Do not pass it to API calls. +#define VK_EXT_shader_replicated_composites 1 +#define VK_EXT_SHADER_REPLICATED_COMPOSITES_SPEC_VERSION 1 +#define VK_EXT_SHADER_REPLICATED_COMPOSITES_EXTENSION_NAME "VK_EXT_shader_replicated_composites" +typedef struct VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT { + VkStructureType sType; + void* pNext; + VkBool32 shaderReplicatedComposites; +} VkPhysicalDeviceShaderReplicatedCompositesFeaturesEXT; + + + +// VK_NV_ray_tracing_validation is a preprocessor guard. Do not pass it to API calls. +#define VK_NV_ray_tracing_validation 1 +#define VK_NV_RAY_TRACING_VALIDATION_SPEC_VERSION 1 +#define VK_NV_RAY_TRACING_VALIDATION_EXTENSION_NAME "VK_NV_ray_tracing_validation" +typedef struct VkPhysicalDeviceRayTracingValidationFeaturesNV { + VkStructureType sType; + void* pNext; + VkBool32 rayTracingValidation; +} VkPhysicalDeviceRayTracingValidationFeaturesNV; + + + +// VK_MESA_image_alignment_control is a preprocessor guard. Do not pass it to API calls. +#define VK_MESA_image_alignment_control 1 +#define VK_MESA_IMAGE_ALIGNMENT_CONTROL_SPEC_VERSION 1 +#define VK_MESA_IMAGE_ALIGNMENT_CONTROL_EXTENSION_NAME "VK_MESA_image_alignment_control" +typedef struct VkPhysicalDeviceImageAlignmentControlFeaturesMESA { + VkStructureType sType; + void* pNext; + VkBool32 imageAlignmentControl; +} VkPhysicalDeviceImageAlignmentControlFeaturesMESA; + +typedef struct VkPhysicalDeviceImageAlignmentControlPropertiesMESA { + VkStructureType sType; + void* pNext; + uint32_t supportedImageAlignmentMask; +} VkPhysicalDeviceImageAlignmentControlPropertiesMESA; + +typedef struct VkImageAlignmentControlCreateInfoMESA { + VkStructureType sType; + const void* pNext; + uint32_t maximumRequestedAlignment; +} VkImageAlignmentControlCreateInfoMESA; + + + // VK_KHR_acceleration_structure is a preprocessor guard. Do not pass it to API calls. #define VK_KHR_acceleration_structure 1 #define VK_KHR_ACCELERATION_STRUCTURE_SPEC_VERSION 13 diff --git a/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_metal.h b/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_metal.h index e6f7bf7..89a5574 100644 --- a/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_metal.h +++ b/libs/bgfx/3rdparty/khronos/vulkan-local/vulkan_metal.h @@ -52,28 +52,28 @@ VKAPI_ATTR VkResult VKAPI_CALL vkCreateMetalSurfaceEXT( #define VK_EXT_metal_objects 1 #ifdef __OBJC__ @protocol MTLDevice; -typedef id MTLDevice_id; +typedef __unsafe_unretained id MTLDevice_id; #else typedef void* MTLDevice_id; #endif #ifdef __OBJC__ @protocol MTLCommandQueue; -typedef id MTLCommandQueue_id; +typedef __unsafe_unretained id MTLCommandQueue_id; #else typedef void* MTLCommandQueue_id; #endif #ifdef __OBJC__ @protocol MTLBuffer; -typedef id MTLBuffer_id; +typedef __unsafe_unretained id MTLBuffer_id; #else typedef void* MTLBuffer_id; #endif #ifdef __OBJC__ @protocol MTLTexture; -typedef id MTLTexture_id; +typedef __unsafe_unretained id MTLTexture_id; #else typedef void* MTLTexture_id; #endif @@ -81,12 +81,12 @@ typedef void* MTLTexture_id; typedef struct __IOSurface* IOSurfaceRef; #ifdef __OBJC__ @protocol MTLSharedEvent; -typedef id MTLSharedEvent_id; +typedef __unsafe_unretained id MTLSharedEvent_id; #else typedef void* MTLSharedEvent_id; #endif -#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 1 +#define VK_EXT_METAL_OBJECTS_SPEC_VERSION 2 #define VK_EXT_METAL_OBJECTS_EXTENSION_NAME "VK_EXT_metal_objects" typedef enum VkExportMetalObjectTypeFlagBitsEXT { diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/allocator.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/allocator.cpp index 072e8e5..12eda38 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/allocator.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/allocator.cpp @@ -1,7 +1,7 @@ // This file is part of meshoptimizer library; see meshoptimizer.h for version/license details #include "meshoptimizer.h" -void meshopt_setAllocator(void* (MESHOPTIMIZER_ALLOC_CALLCONV *allocate)(size_t), void (MESHOPTIMIZER_ALLOC_CALLCONV *deallocate)(void*)) +void meshopt_setAllocator(void*(MESHOPTIMIZER_ALLOC_CALLCONV* allocate)(size_t), void(MESHOPTIMIZER_ALLOC_CALLCONV* deallocate)(void*)) { meshopt_Allocator::Storage::allocate = allocate; meshopt_Allocator::Storage::deallocate = deallocate; diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/clusterizer.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/clusterizer.cpp index c4672ad..52fe5a3 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/clusterizer.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/clusterizer.cpp @@ -441,7 +441,7 @@ static size_t kdtreeBuild(size_t offset, KDNode* nodes, size_t node_count, const } // split axis is one where the variance is largest - unsigned int axis = vars[0] >= vars[1] && vars[0] >= vars[2] ? 0 : vars[1] >= vars[2] ? 1 : 2; + unsigned int axis = (vars[0] >= vars[1] && vars[0] >= vars[2]) ? 0 : (vars[1] >= vars[2] ? 1 : 2); float split = mean[axis]; size_t middle = kdtreePartition(indices, count, points, stride, axis, split); @@ -882,3 +882,93 @@ meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices return meshopt_computeClusterBounds(indices, triangle_count * 3, vertex_positions, vertex_count, vertex_positions_stride); } + +void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count) +{ + using namespace meshopt; + + assert(triangle_count <= kMeshletMaxTriangles); + assert(vertex_count <= kMeshletMaxVertices); + + unsigned char* indices = meshlet_triangles; + unsigned int* vertices = meshlet_vertices; + + // cache tracks vertex timestamps (corresponding to triangle index! all 3 vertices are added at the same time and never removed) + unsigned char cache[kMeshletMaxVertices]; + memset(cache, 0, vertex_count); + + // note that we start from a value that means all vertices aren't in cache + unsigned char cache_last = 128; + const unsigned char cache_cutoff = 3; // 3 triangles = ~5..9 vertices depending on reuse + + for (size_t i = 0; i < triangle_count; ++i) + { + int next = -1; + int next_match = -1; + + for (size_t j = i; j < triangle_count; ++j) + { + unsigned char a = indices[j * 3 + 0], b = indices[j * 3 + 1], c = indices[j * 3 + 2]; + assert(a < vertex_count && b < vertex_count && c < vertex_count); + + // score each triangle by how many vertices are in cache + // note: the distance is computed using unsigned 8-bit values, so cache timestamp overflow is handled gracefully + int aok = (unsigned char)(cache_last - cache[a]) < cache_cutoff; + int bok = (unsigned char)(cache_last - cache[b]) < cache_cutoff; + int cok = (unsigned char)(cache_last - cache[c]) < cache_cutoff; + + if (aok + bok + cok > next_match) + { + next = (int)j; + next_match = aok + bok + cok; + + // note that we could end up with all 3 vertices in the cache, but 2 is enough for ~strip traversal + if (next_match >= 2) + break; + } + } + + assert(next >= 0); + + unsigned char a = indices[next * 3 + 0], b = indices[next * 3 + 1], c = indices[next * 3 + 2]; + + // shift triangles before the next one forward so that we always keep an ordered partition + // note: this could have swapped triangles [i] and [next] but that distorts the order and may skew the output sequence + memmove(indices + (i + 1) * 3, indices + i * 3, (next - i) * 3 * sizeof(unsigned char)); + + indices[i * 3 + 0] = a; + indices[i * 3 + 1] = b; + indices[i * 3 + 2] = c; + + // cache timestamp is the same between all vertices of each triangle to reduce overflow + cache_last++; + cache[a] = cache_last; + cache[b] = cache_last; + cache[c] = cache_last; + } + + // reorder meshlet vertices for access locality assuming index buffer is scanned sequentially + unsigned int order[kMeshletMaxVertices]; + + unsigned char remap[kMeshletMaxVertices]; + memset(remap, -1, vertex_count); + + size_t vertex_offset = 0; + + for (size_t i = 0; i < triangle_count * 3; ++i) + { + unsigned char& r = remap[indices[i]]; + + if (r == 0xff) + { + r = (unsigned char)(vertex_offset); + order[vertex_offset] = vertices[indices[i]]; + vertex_offset++; + } + + indices[i] = r; + } + + assert(vertex_offset <= vertex_count); + memcpy(vertices, order, vertex_offset * sizeof(unsigned int)); +} diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/indexcodec.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/indexcodec.cpp index 4cc2fea..b300460 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/indexcodec.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/indexcodec.cpp @@ -33,7 +33,7 @@ static int rotateTriangle(unsigned int a, unsigned int b, unsigned int c, unsign { (void)a; - return (b == next) ? 1 : (c == next) ? 2 : 0; + return (b == next) ? 1 : (c == next ? 2 : 0); } static int getEdgeFifo(EdgeFifo fifo, unsigned int a, unsigned int b, unsigned int c, size_t offset) @@ -217,7 +217,7 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons int fe = fer >> 2; int fc = getVertexFifo(vertexfifo, c, vertexfifooffset); - int fec = (fc >= 1 && fc < fecmax) ? fc : (c == next) ? (next++, 0) : 15; + int fec = (fc >= 1 && fc < fecmax) ? fc : (c == next ? (next++, 0) : 15); if (fec == 15 && version >= 1) { @@ -267,8 +267,8 @@ size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, cons // after rotation, a is almost always equal to next, so we don't waste bits on FIFO encoding for a int fea = (a == next) ? (next++, 0) : 15; - int feb = (fb >= 0 && fb < 14) ? (fb + 1) : (b == next) ? (next++, 0) : 15; - int fec = (fc >= 0 && fc < 14) ? (fc + 1) : (c == next) ? (next++, 0) : 15; + int feb = (fb >= 0 && fb < 14) ? fb + 1 : (b == next ? (next++, 0) : 15); + int fec = (fc >= 0 && fc < 14) ? fc + 1 : (c == next ? (next++, 0) : 15); // we encode feb & fec in 4 bits using a table if possible, and as a full byte otherwise unsigned char codeaux = (unsigned char)((feb << 4) | fec); diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/meshoptimizer.h b/libs/bgfx/3rdparty/meshoptimizer/src/meshoptimizer.h index 0619cec..6c8dcd7 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/meshoptimizer.h +++ b/libs/bgfx/3rdparty/meshoptimizer/src/meshoptimizer.h @@ -1,5 +1,5 @@ /** - * meshoptimizer - version 0.20 + * meshoptimizer - version 0.21 * * Copyright (C) 2016-2024, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at https://github.com/zeux/meshoptimizer @@ -12,7 +12,7 @@ #include /* Version macro; major * 1000 + minor * 10 + patch */ -#define MESHOPTIMIZER_VERSION 200 /* 0.20 */ +#define MESHOPTIMIZER_VERSION 210 /* 0.21 */ /* If no API is defined, assume default */ #ifndef MESHOPTIMIZER_API @@ -311,12 +311,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t cou */ enum meshopt_EncodeExpMode { - /* When encoding exponents, use separate values for each component (maximum quality) */ - meshopt_EncodeExpSeparate, - /* When encoding exponents, use shared value for all components of each vector (better compression) */ - meshopt_EncodeExpSharedVector, - /* When encoding exponents, use shared value for each component of all vectors (best compression) */ - meshopt_EncodeExpSharedComponent, + /* When encoding exponents, use separate values for each component (maximum quality) */ + meshopt_EncodeExpSeparate, + /* When encoding exponents, use shared value for all components of each vector (better compression) */ + meshopt_EncodeExpSharedVector, + /* When encoding exponents, use shared value for each component of all vectors (best compression) */ + meshopt_EncodeExpSharedComponent, }; MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data); @@ -328,8 +328,12 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_ */ enum { - /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ - meshopt_SimplifyLockBorder = 1 << 0, + /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */ + meshopt_SimplifyLockBorder = 1 << 0, + /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */ + meshopt_SimplifySparse = 1 << 1, + /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */ + meshopt_SimplifyErrorAbsolute = 1 << 2, }; /** @@ -357,9 +361,10 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig * vertex_attributes should have attribute_count floats for each vertex * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range. * attribute_count must be <= 16 + * vertex_lock can be NULL; when it's not NULL, it should have a value for each vertex; 1 denotes vertices that can't be moved * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future */ -MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error); +MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error); /** * Experimental: Mesh simplifier (sloppy) @@ -493,6 +498,16 @@ MESHOPTIMIZER_API size_t meshopt_buildMeshlets(struct meshopt_Meshlet* meshlets, MESHOPTIMIZER_API size_t meshopt_buildMeshletsScan(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles); MESHOPTIMIZER_API size_t meshopt_buildMeshletsBound(size_t index_count, size_t max_vertices, size_t max_triangles); +/** + * Experimental: Meshlet optimizer + * Reorders meshlet vertices and triangles to maximize locality to improve rasterizer throughput + * + * meshlet_triangles and meshlet_vertices must refer to meshlet triangle and vertex index data; when buildMeshlets* is used, these + * need to be computed from meshlet's vertex_offset and triangle_offset + * triangle_count and vertex_count must not exceed implementation limits (vertex_count <= 255 - not 256!, triangle_count <= 512) + */ +MESHOPTIMIZER_EXPERIMENTAL void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count); + struct meshopt_Bounds { /* bounding sphere, useful for frustum and occlusion culling */ @@ -649,7 +664,7 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const template inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); template -inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); +inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL); template inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = NULL); template @@ -956,12 +971,12 @@ inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_co } template -inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error) +inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error) { - meshopt_IndexAdapter in(NULL, indices, index_count); - meshopt_IndexAdapter out(destination, NULL, index_count); + meshopt_IndexAdapter in(NULL, indices, index_count); + meshopt_IndexAdapter out(destination, NULL, index_count); - return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, target_index_count, target_error, options, result_error); + return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, result_error); } template diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/simplifier.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/simplifier.cpp index 4073bb4..e59b4af 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/simplifier.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/simplifier.cpp @@ -111,10 +111,12 @@ struct PositionHasher { const float* vertex_positions; size_t vertex_stride_float; + const unsigned int* sparse_remap; size_t hash(unsigned int index) const { - const unsigned int* key = reinterpret_cast(vertex_positions + index * vertex_stride_float); + unsigned int ri = sparse_remap ? sparse_remap[index] : index; + const unsigned int* key = reinterpret_cast(vertex_positions + ri * vertex_stride_float); // scramble bits to make sure that integer coordinates have entropy in lower bits unsigned int x = key[0] ^ (key[0] >> 17); @@ -127,7 +129,25 @@ struct PositionHasher bool equal(unsigned int lhs, unsigned int rhs) const { - return memcmp(vertex_positions + lhs * vertex_stride_float, vertex_positions + rhs * vertex_stride_float, sizeof(float) * 3) == 0; + unsigned int li = sparse_remap ? sparse_remap[lhs] : lhs; + unsigned int ri = sparse_remap ? sparse_remap[rhs] : rhs; + + return memcmp(vertex_positions + li * vertex_stride_float, vertex_positions + ri * vertex_stride_float, sizeof(float) * 3) == 0; + } +}; + +struct RemapHasher +{ + unsigned int* remap; + + size_t hash(unsigned int id) const + { + return id * 0x5bd1e995; + } + + bool equal(unsigned int lhs, unsigned int rhs) const + { + return remap[lhs] == rhs; } }; @@ -167,9 +187,9 @@ static T* hashLookup2(T* table, size_t buckets, const Hash& hash, const T& key, return NULL; } -static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator) +static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* sparse_remap, meshopt_Allocator& allocator) { - PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float)}; + PositionHasher hasher = {vertex_positions_data, vertex_positions_stride / sizeof(float), sparse_remap}; size_t table_size = hashBuckets2(vertex_count); unsigned int* table = allocator.allocate(table_size); @@ -205,6 +225,57 @@ static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const f allocator.deallocate(table); } +static unsigned int* buildSparseRemap(unsigned int* indices, size_t index_count, size_t vertex_count, size_t* out_vertex_count, meshopt_Allocator& allocator) +{ + // use a bit set to compute the precise number of unique vertices + unsigned char* filter = allocator.allocate((vertex_count + 7) / 8); + memset(filter, 0, (vertex_count + 7) / 8); + + size_t unique = 0; + for (size_t i = 0; i < index_count; ++i) + { + unsigned int index = indices[i]; + assert(index < vertex_count); + + unique += (filter[index / 8] & (1 << (index % 8))) == 0; + filter[index / 8] |= 1 << (index % 8); + } + + unsigned int* remap = allocator.allocate(unique); + size_t offset = 0; + + // temporary map dense => sparse; we allocate it last so that we can deallocate it + size_t revremap_size = hashBuckets2(unique); + unsigned int* revremap = allocator.allocate(revremap_size); + memset(revremap, -1, revremap_size * sizeof(unsigned int)); + + // fill remap, using revremap as a helper, and rewrite indices in the same pass + RemapHasher hasher = {remap}; + + for (size_t i = 0; i < index_count; ++i) + { + unsigned int index = indices[i]; + + unsigned int* entry = hashLookup2(revremap, revremap_size, hasher, index, ~0u); + + if (*entry == ~0u) + { + remap[offset] = index; + *entry = unsigned(offset); + offset++; + } + + indices[i] = *entry; + } + + allocator.deallocate(revremap); + + assert(offset == unique); + *out_vertex_count = unique; + + return remap; +} + enum VertexKind { Kind_Manifold, // not on an attribute seam, not on any boundary @@ -252,7 +323,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int return false; } -static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options) +static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_lock, const unsigned int* sparse_remap, unsigned int options) { memset(loop, -1, vertex_count * sizeof(unsigned int)); memset(loopback, -1, vertex_count * sizeof(unsigned int)); @@ -298,7 +369,12 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned { if (remap[i] == i) { - if (wedge[i] == i) + if (vertex_lock && vertex_lock[sparse_remap ? sparse_remap[i] : i]) + { + // vertex is explicitly locked + result[i] = Kind_Locked; + } + else if (wedge[i] == i) { // no attribute seam, need to check if it's manifold unsigned int openi = openinc[i], openo = openout[i]; @@ -378,7 +454,7 @@ struct Vector3 float x, y, z; }; -static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride) +static float rescalePositions(Vector3* result, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const unsigned int* sparse_remap = NULL) { size_t vertex_stride_float = vertex_positions_stride / sizeof(float); @@ -387,7 +463,8 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat for (size_t i = 0; i < vertex_count; ++i) { - const float* v = vertex_positions_data + i * vertex_stride_float; + unsigned int ri = sparse_remap ? sparse_remap[i] : unsigned(i); + const float* v = vertex_positions_data + ri * vertex_stride_float; if (result) { @@ -426,15 +503,17 @@ static float rescalePositions(Vector3* result, const float* vertex_positions_dat return extent; } -static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count) +static void rescaleAttributes(float* result, const float* vertex_attributes_data, size_t vertex_count, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned int* sparse_remap) { size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float); for (size_t i = 0; i < vertex_count; ++i) { + unsigned int ri = sparse_remap ? sparse_remap[i] : unsigned(i); + for (size_t k = 0; k < attribute_count; ++k) { - float a = vertex_attributes_data[i * vertex_attributes_stride_float + k]; + float a = vertex_attributes_data[ri * vertex_attributes_stride_float + k]; result[i * attribute_count + k] = a * attribute_weights[k]; } @@ -813,7 +892,13 @@ static bool hasTriangleFlip(const Vector3& a, const Vector3& b, const Vector3& c Vector3 nbc = {eb.y * ec.z - eb.z * ec.y, eb.z * ec.x - eb.x * ec.z, eb.x * ec.y - eb.y * ec.x}; Vector3 nbd = {eb.y * ed.z - eb.z * ed.y, eb.z * ed.x - eb.x * ed.z, eb.x * ed.y - eb.y * ed.x}; - return nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z <= 0; + float ndp = nbc.x * nbd.x + nbc.y * nbd.y + nbc.z * nbd.z; + float abc = nbc.x * nbc.x + nbc.y * nbc.y + nbc.z * nbc.z; + float abd = nbd.x * nbd.x + nbd.y * nbd.y + nbd.z * nbd.z; + + // scale is cos(angle); somewhat arbitrarily set to ~75 degrees + // note that the "pure" check is ndp <= 0 (90 degree cutoff) but that allows flipping through a series of close-to-90 collapses + return ndp <= 0.25f * sqrtf(abc * abd); } static bool hasTriangleFlips(const EdgeAdjacency& adjacency, const Vector3* vertex_positions, const unsigned int* collapse_remap, unsigned int i0, unsigned int i1) @@ -1305,7 +1390,7 @@ static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices unsigned int c1 = vertex_cells[i1]; unsigned int c2 = vertex_cells[i2]; - bool single_cell = (c0 == c1) & (c0 == c2); + int single_cell = (c0 == c1) & (c0 == c2); Quadric Q; quadricFromTriangle(Q, vertex_positions[i0], vertex_positions[i1], vertex_positions[i2], single_cell ? 3.f : 1.f); @@ -1468,7 +1553,7 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL; MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL; #endif -size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { using namespace meshopt; @@ -1476,7 +1561,7 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256); assert(vertex_positions_stride % sizeof(float) == 0); assert(target_index_count <= index_count); - assert((options & ~(meshopt_SimplifyLockBorder)) == 0); + assert((options & ~(meshopt_SimplifyLockBorder | meshopt_SimplifySparse | meshopt_SimplifyErrorAbsolute)) == 0); assert(vertex_attributes_stride >= attribute_count * sizeof(float) && vertex_attributes_stride <= 256); assert(vertex_attributes_stride % sizeof(float) == 0); assert(attribute_count <= kMaxAttributes); @@ -1484,22 +1569,30 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic meshopt_Allocator allocator; unsigned int* result = destination; + if (result != indices) + memcpy(result, indices, index_count * sizeof(unsigned int)); + + // build an index remap and update indices/vertex_count to minimize the subsequent work + // note: as a consequence, errors will be computed relative to the subset extent + unsigned int* sparse_remap = NULL; + if (options & meshopt_SimplifySparse) + sparse_remap = buildSparseRemap(result, index_count, vertex_count, &vertex_count, allocator); // build adjacency information EdgeAdjacency adjacency = {}; prepareEdgeAdjacency(adjacency, index_count, vertex_count, allocator); - updateEdgeAdjacency(adjacency, indices, index_count, vertex_count, NULL); + updateEdgeAdjacency(adjacency, result, index_count, vertex_count, NULL); // build position remap that maps each vertex to the one with identical position unsigned int* remap = allocator.allocate(vertex_count); unsigned int* wedge = allocator.allocate(vertex_count); - buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, allocator); + buildPositionRemap(remap, wedge, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap, allocator); // classify vertices; vertex kind determines collapse rules, see kCanCollapse unsigned char* vertex_kind = allocator.allocate(vertex_count); unsigned int* loop = allocator.allocate(vertex_count); unsigned int* loopback = allocator.allocate(vertex_count); - classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options); + classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, vertex_lock, sparse_remap, options); #if TRACE size_t unique_positions = 0; @@ -1517,14 +1610,14 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic #endif Vector3* vertex_positions = allocator.allocate(vertex_count); - rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride); + float vertex_scale = rescalePositions(vertex_positions, vertex_positions_data, vertex_count, vertex_positions_stride, sparse_remap); float* vertex_attributes = NULL; if (attribute_count) { vertex_attributes = allocator.allocate(vertex_count * attribute_count); - rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count); + rescaleAttributes(vertex_attributes, vertex_attributes_data, vertex_count, vertex_attributes_stride, attribute_weights, attribute_count, sparse_remap); } Quadric* vertex_quadrics = allocator.allocate(vertex_count); @@ -1542,14 +1635,11 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic memset(attribute_gradients, 0, vertex_count * attribute_count * sizeof(QuadricGrad)); } - fillFaceQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap); - fillEdgeQuadrics(vertex_quadrics, indices, index_count, vertex_positions, remap, vertex_kind, loop, loopback); + fillFaceQuadrics(vertex_quadrics, result, index_count, vertex_positions, remap); + fillEdgeQuadrics(vertex_quadrics, result, index_count, vertex_positions, remap, vertex_kind, loop, loopback); if (attribute_count) - fillAttributeQuadrics(attribute_quadrics, attribute_gradients, indices, index_count, vertex_positions, vertex_attributes, attribute_count, remap); - - if (result != indices) - memcpy(result, indices, index_count * sizeof(unsigned int)); + fillAttributeQuadrics(attribute_quadrics, attribute_gradients, result, index_count, vertex_positions, vertex_attributes, attribute_count, remap); #if TRACE size_t pass_count = 0; @@ -1566,7 +1656,8 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic float result_error = 0; // target_error input is linear; we need to adjust it to match quadricError units - float error_limit = target_error * target_error; + float error_scale = (options & meshopt_SimplifyErrorAbsolute) ? vertex_scale : 1.f; + float error_limit = (target_error * target_error) / (error_scale * error_scale); while (result_count > target_index_count) { @@ -1625,21 +1716,26 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic memcpy(meshopt_simplifyDebugLoopBack, loopback, vertex_count * sizeof(unsigned int)); #endif + // convert resulting indices back into the dense space of the larger mesh + if (sparse_remap) + for (size_t i = 0; i < result_count; ++i) + result[i] = sparse_remap[result[i]]; + // result_error is quadratic; we need to remap it back to linear if (out_result_error) - *out_result_error = sqrtf(result_error); + *out_result_error = sqrtf(result_error) * error_scale; return result_count; } size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, NULL, 0, NULL, 0, NULL, target_index_count, target_error, options, out_result_error); } -size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) +size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* out_result_error) { - return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, target_index_count, target_error, options, out_result_error); + return meshopt_simplifyEdge(destination, indices, index_count, vertex_positions_data, vertex_count, vertex_positions_stride, vertex_attributes_data, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, out_result_error); } size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error) @@ -1692,14 +1788,14 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid ? max_grid - 1 : grid_size); computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t triangles = countTriangles(vertex_ids, indices, index_count); #if TRACE printf("pass %d (%s): grid size %d, triangles %d, %s\n", - pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary", + pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses ? "lerp" : "binary"), grid_size, int(triangles), (triangles <= target_index_count / 3) ? "under" : "over"); #endif @@ -1824,14 +1920,14 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos // we clamp the prediction of the grid size to make sure that the search converges int grid_size = next_grid_size; - grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid) ? max_grid - 1 : grid_size; + grid_size = (grid_size <= min_grid) ? min_grid + 1 : (grid_size >= max_grid ? max_grid - 1 : grid_size); computeVertexIds(vertex_ids, vertex_positions, vertex_count, grid_size); size_t vertices = countVertexCells(table, table_size, vertex_ids, vertex_count); #if TRACE printf("pass %d (%s): grid size %d, vertices %d, %s\n", - pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses) ? "lerp" : "binary", + pass, (pass == 0) ? "guess" : (pass <= kInterpolationPasses ? "lerp" : "binary"), grid_size, int(vertices), (vertices <= target_vertex_count) ? "under" : "over"); #endif diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/stripifier.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/stripifier.cpp index 8ce17ef..d57fb51 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/stripifier.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/stripifier.cpp @@ -18,7 +18,7 @@ static unsigned int findStripFirst(const unsigned int buffer[][3], unsigned int for (size_t i = 0; i < buffer_size; ++i) { unsigned int va = valence[buffer[i][0]], vb = valence[buffer[i][1]], vc = valence[buffer[i][2]]; - unsigned int v = (va < vb && va < vc) ? va : (vb < vc) ? vb : vc; + unsigned int v = (va < vb && va < vc) ? va : (vb < vc ? vb : vc); if (v < iv) { diff --git a/libs/bgfx/3rdparty/meshoptimizer/src/vertexcodec.cpp b/libs/bgfx/3rdparty/meshoptimizer/src/vertexcodec.cpp index 8ab0662..94f7a1a 100644 --- a/libs/bgfx/3rdparty/meshoptimizer/src/vertexcodec.cpp +++ b/libs/bgfx/3rdparty/meshoptimizer/src/vertexcodec.cpp @@ -245,7 +245,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end, } } - int bitslog2 = (best_bits == 1) ? 0 : (best_bits == 2) ? 1 : (best_bits == 4) ? 2 : 3; + int bitslog2 = (best_bits == 1) ? 0 : (best_bits == 2 ? 1 : (best_bits == 4 ? 2 : 3)); assert((1 << bitslog2) == best_bits); size_t header_offset = i / kByteGroupSize; diff --git a/libs/bgfx/3rdparty/spirv-cross/main.cpp b/libs/bgfx/3rdparty/spirv-cross/main.cpp index 7e14f11..6361fc8 100644 --- a/libs/bgfx/3rdparty/spirv-cross/main.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/main.cpp @@ -675,11 +675,13 @@ struct CLIArguments bool msl_force_sample_rate_shading = false; bool msl_manual_helper_invocation_updates = true; bool msl_check_discarded_frag_stores = false; + bool msl_force_fragment_with_side_effects_execution = false; bool msl_sample_dref_lod_array_as_grad = false; bool msl_runtime_array_rich_descriptor = false; bool msl_replace_recursive_inputs = false; bool msl_readwrite_texture_fences = true; bool msl_agx_manual_cube_grad_fixup = false; + bool msl_input_attachment_is_ds_attachment = false; const char *msl_combined_sampler_suffix = nullptr; bool glsl_emit_push_constant_as_ubo = false; bool glsl_emit_ubo_as_plain_uniforms = false; @@ -872,6 +874,10 @@ static void print_help_msl() "\t[--msl-runtime-array-rich-descriptor]:\n\t\tWhen declaring a runtime array of SSBOs, declare an array of {ptr, len} pairs to support OpArrayLength.\n" "\t[--msl-replace-recursive-inputs]:\n\t\tWorks around a Metal 3.1 regression bug, which causes an infinite recursion crash during Metal's analysis of an entry point input structure that itself contains internal recursion.\n" "\t[--msl-texture-buffer-native]:\n\t\tEnable native support for texel buffers. Otherwise, it is emulated as a normal texture.\n" + "\t[--msl-input-attachment-is-ds-attachment]:\n\t\tAdds a simple depth passthrough in fragment shaders when they do not modify the depth value.\n" + "\t\tRequired to force Metal to write to the depth/stencil attachment post fragment execution.\n" + "\t\tOtherwise, Metal may optimize the write to pre fragment execution which goes against the Vulkan spec.\n" + "\t\tOnly required if an input attachment and depth/stencil attachment reference the same resource.\n" "\t[--msl-framebuffer-fetch]:\n\t\tImplement subpass inputs with frame buffer fetch.\n" "\t\tEmits [[color(N)]] inputs in fragment stage.\n" "\t\tRequires an Apple GPU.\n" @@ -956,6 +962,15 @@ static void print_help_msl() "\t\tSome Metal devices have a bug where stores to resources from a fragment shader\n" "\t\tcontinue to execute, even when the fragment is discarded. These checks\n" "\t\tprevent these stores from executing.\n" + "\t[--msl-force-frag-execution]:\n\t\tEnforces fragment execution to avoid early discard by Metal\n" + "\t\tMetal will prematurely discard fragments before execution when side effects are present.\n" + "\t\tThis condition is triggered under the following conditions (side effect operations happen before discard):\n" + "\t\t\t1. Pre fragment depth test fails.\n" + "\t\t\t2. Modify depth value in fragment shader to constant value known at compile time.\n" + "\t\t\t3. Constant value will not pass post fragment depth test.\n" + "\t\t\t4. Fragment is always discarded in fragment execution.\n" + "\t\tHowever, Vulkan expects fragment shader to be executed since it cannot be discarded until the discard\n" + "\t\tpresent in the fragment execution, which would also execute the operations with side effects.\n" "\t[--msl-sample-dref-lod-array-as-grad]:\n\t\tUse a gradient instead of a level argument.\n" "\t\tSome Metal devices have a bug where the level() argument to\n" "\t\tdepth2d_array::sample_compare() in a fragment shader is biased by some\n" @@ -1242,10 +1257,12 @@ static string compile_iteration(const CLIArguments &args, std::vector msl_opts.force_sample_rate_shading = args.msl_force_sample_rate_shading; msl_opts.manual_helper_invocation_updates = args.msl_manual_helper_invocation_updates; msl_opts.check_discarded_frag_stores = args.msl_check_discarded_frag_stores; + msl_opts.force_fragment_with_side_effects_execution = args.msl_force_fragment_with_side_effects_execution; msl_opts.sample_dref_lod_array_as_grad = args.msl_sample_dref_lod_array_as_grad; msl_opts.ios_support_base_vertex_instance = true; msl_opts.runtime_array_rich_descriptor = args.msl_runtime_array_rich_descriptor; msl_opts.replace_recursive_inputs = args.msl_replace_recursive_inputs; + msl_opts.input_attachment_is_ds_attachment = args.msl_input_attachment_is_ds_attachment; msl_opts.readwrite_texture_fences = args.msl_readwrite_texture_fences; msl_opts.agx_manual_cube_grad_fixup = args.msl_agx_manual_cube_grad_fixup; msl_comp->set_msl_options(msl_opts); @@ -1800,6 +1817,7 @@ static int main_inner(int argc, char *argv[]) cbs.add("--msl-no-manual-helper-invocation-updates", [&args](CLIParser &) { args.msl_manual_helper_invocation_updates = false; }); cbs.add("--msl-check-discarded-frag-stores", [&args](CLIParser &) { args.msl_check_discarded_frag_stores = true; }); + cbs.add("--msl-force-frag-with-side-effects-execution", [&args](CLIParser &) { args.msl_force_fragment_with_side_effects_execution = true; }); cbs.add("--msl-sample-dref-lod-array-as-grad", [&args](CLIParser &) { args.msl_sample_dref_lod_array_as_grad = true; }); cbs.add("--msl-no-readwrite-texture-fences", [&args](CLIParser &) { args.msl_readwrite_texture_fences = false; }); @@ -1811,6 +1829,7 @@ static int main_inner(int argc, char *argv[]) [&args](CLIParser &) { args.msl_runtime_array_rich_descriptor = true; }); cbs.add("--msl-replace-recursive-inputs", [&args](CLIParser &) { args.msl_replace_recursive_inputs = true; }); + cbs.add("--msl-input-attachment-is-ds-attachment", [&args](CLIParser &) { args.msl_input_attachment_is_ds_attachment = true; }); cbs.add("--extension", [&args](CLIParser &parser) { args.extensions.push_back(parser.next_string()); }); cbs.add("--rename-entry-point", [&args](CLIParser &parser) { auto old_name = parser.next_string(); diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_common.hpp b/libs/bgfx/3rdparty/spirv-cross/spirv_common.hpp index 51fffe7..93b2669 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_common.hpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_common.hpp @@ -1121,6 +1121,9 @@ struct SPIRVariable : IVariant // Set to true while we're inside the for loop. bool loop_variable_enable = false; + // Used to find global LUTs + bool is_written_to = false; + SPIRFunction::Parameter *parameter = nullptr; SPIRV_CROSS_DECLARE_CLONE(SPIRVariable) @@ -1668,6 +1671,8 @@ enum ExtendedDecorations // lack of constructors in the 'threadgroup' address space. SPIRVCrossDecorationWorkgroupStruct, + SPIRVCrossDecorationOverlappingBinding, + SPIRVCrossDecorationCount }; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cpp.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_cpp.cpp index dd0a84c..61c30e9 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cpp.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cpp.cpp @@ -40,7 +40,7 @@ void CompilerCPP::emit_buffer_block(const SPIRVariable &var) emit_block_struct(type); auto buffer_name = to_name(type.self); - statement("internal::Resource<", buffer_name, type_to_array_glsl(type), "> ", instance_name, "__;"); + statement("internal::Resource<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;"); statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()"); resource_registrations.push_back( join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");")); @@ -68,7 +68,7 @@ void CompilerCPP::emit_interface_block(const SPIRVariable &var) else buffer_name = type_to_glsl(type); - statement("internal::", qual, "<", buffer_name, type_to_array_glsl(type), "> ", instance_name, "__;"); + statement("internal::", qual, "<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;"); statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()"); resource_registrations.push_back(join("s.register_", lowerqual, "(", instance_name, "__", ", ", location, ");")); statement(""); @@ -100,14 +100,14 @@ void CompilerCPP::emit_uniform(const SPIRVariable &var) if (type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::AtomicCounter) { - statement("internal::Resource<", type_name, type_to_array_glsl(type), "> ", instance_name, "__;"); + statement("internal::Resource<", type_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;"); statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()"); resource_registrations.push_back( join("s.register_resource(", instance_name, "__", ", ", descriptor_set, ", ", binding, ");")); } else { - statement("internal::UniformConstant<", type_name, type_to_array_glsl(type), "> ", instance_name, "__;"); + statement("internal::UniformConstant<", type_name, type_to_array_glsl(type, var.self), "> ", instance_name, "__;"); statement_no_indent("#define ", instance_name, " __res->", instance_name, "__.get()"); resource_registrations.push_back( join("s.register_uniform_constant(", instance_name, "__", ", ", location, ");")); @@ -130,7 +130,7 @@ void CompilerCPP::emit_push_constant_block(const SPIRVariable &var) auto buffer_name = to_name(type.self); auto instance_name = to_name(var.self); - statement("internal::PushConstant<", buffer_name, type_to_array_glsl(type), "> ", instance_name, ";"); + statement("internal::PushConstant<", buffer_name, type_to_array_glsl(type, var.self), "> ", instance_name, ";"); statement_no_indent("#define ", instance_name, " __res->", instance_name, ".get()"); resource_registrations.push_back(join("s.register_push_constant(", instance_name, "__", ");")); statement(""); diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cross.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_cross.cpp index 3f0fec3..8c3e7d3 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cross.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cross.cpp @@ -93,6 +93,97 @@ bool Compiler::variable_storage_is_aliased(const SPIRVariable &v) return !is_restrict && (ssbo || image || counter || buffer_reference); } +bool Compiler::block_is_control_dependent(const SPIRBlock &block) +{ + for (auto &i : block.ops) + { + auto ops = stream(i); + auto op = static_cast(i.op); + + switch (op) + { + case OpFunctionCall: + { + uint32_t func = ops[2]; + if (function_is_control_dependent(get(func))) + return true; + break; + } + + // Derivatives + case OpDPdx: + case OpDPdxCoarse: + case OpDPdxFine: + case OpDPdy: + case OpDPdyCoarse: + case OpDPdyFine: + case OpFwidth: + case OpFwidthCoarse: + case OpFwidthFine: + + // Anything implicit LOD + case OpImageSampleImplicitLod: + case OpImageSampleDrefImplicitLod: + case OpImageSampleProjImplicitLod: + case OpImageSampleProjDrefImplicitLod: + case OpImageSparseSampleImplicitLod: + case OpImageSparseSampleDrefImplicitLod: + case OpImageSparseSampleProjImplicitLod: + case OpImageSparseSampleProjDrefImplicitLod: + case OpImageQueryLod: + case OpImageDrefGather: + case OpImageGather: + case OpImageSparseDrefGather: + case OpImageSparseGather: + + // Anything subgroups + case OpGroupNonUniformElect: + case OpGroupNonUniformAll: + case OpGroupNonUniformAny: + case OpGroupNonUniformAllEqual: + case OpGroupNonUniformBroadcast: + case OpGroupNonUniformBroadcastFirst: + case OpGroupNonUniformBallot: + case OpGroupNonUniformInverseBallot: + case OpGroupNonUniformBallotBitExtract: + case OpGroupNonUniformBallotBitCount: + case OpGroupNonUniformBallotFindLSB: + case OpGroupNonUniformBallotFindMSB: + case OpGroupNonUniformShuffle: + case OpGroupNonUniformShuffleXor: + case OpGroupNonUniformShuffleUp: + case OpGroupNonUniformShuffleDown: + case OpGroupNonUniformIAdd: + case OpGroupNonUniformFAdd: + case OpGroupNonUniformIMul: + case OpGroupNonUniformFMul: + case OpGroupNonUniformSMin: + case OpGroupNonUniformUMin: + case OpGroupNonUniformFMin: + case OpGroupNonUniformSMax: + case OpGroupNonUniformUMax: + case OpGroupNonUniformFMax: + case OpGroupNonUniformBitwiseAnd: + case OpGroupNonUniformBitwiseOr: + case OpGroupNonUniformBitwiseXor: + case OpGroupNonUniformLogicalAnd: + case OpGroupNonUniformLogicalOr: + case OpGroupNonUniformLogicalXor: + case OpGroupNonUniformQuadBroadcast: + case OpGroupNonUniformQuadSwap: + + // Control barriers + case OpControlBarrier: + return true; + + default: + break; + } + } + + return false; +} + bool Compiler::block_is_pure(const SPIRBlock &block) { // This is a global side effect of the function. @@ -247,18 +338,21 @@ string Compiler::to_name(uint32_t id, bool allow_alias) const bool Compiler::function_is_pure(const SPIRFunction &func) { for (auto block : func.blocks) - { if (!block_is_pure(get(block))) - { - //fprintf(stderr, "Function %s is impure!\n", to_name(func.self).c_str()); return false; - } - } - //fprintf(stderr, "Function %s is pure!\n", to_name(func.self).c_str()); return true; } +bool Compiler::function_is_control_dependent(const SPIRFunction &func) +{ + for (auto block : func.blocks) + if (block_is_control_dependent(get(block))) + return true; + + return false; +} + void Compiler::register_global_read_dependencies(const SPIRBlock &block, uint32_t id) { for (auto &i : block.ops) @@ -1227,7 +1321,7 @@ const SPIRType &Compiler::get_pointee_type(uint32_t type_id) const uint32_t Compiler::get_variable_data_type_id(const SPIRVariable &var) const { - if (var.phi_variable) + if (var.phi_variable || var.storage == spv::StorageClass::StorageClassAtomicCounter) return var.basetype; return get_pointee_type_id(var.basetype); } @@ -3335,13 +3429,11 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle_terminator(const SPIRBl bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint32_t *args, uint32_t length) { // Keep track of the types of temporaries, so we can hoist them out as necessary. - uint32_t result_type, result_id; + uint32_t result_type = 0, result_id = 0; if (compiler.instruction_to_result_type(result_type, result_id, op, args, length)) { // For some opcodes, we will need to override the result id. // If we need to hoist the temporary, the temporary type is the input, not the result. - // FIXME: This will likely break with OpCopyObject + hoisting, but we'll have to - // solve it if we ever get there ... if (op == OpConvertUToAccelerationStructureKHR) { auto itr = result_id_to_type.find(args[2]); @@ -3450,6 +3542,13 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3 case OpCopyObject: { + // OpCopyObject copies the underlying non-pointer type, + // so any temp variable should be declared using the underlying type. + // If the type is a pointer, get its base type and overwrite the result type mapping. + auto &type = compiler.get(result_type); + if (type.pointer) + result_id_to_type[result_id] = type.parent_type; + if (length < 3) return false; @@ -3731,6 +3830,14 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab auto &var = get(accessed_var.first); auto &type = expression_type(accessed_var.first); + // First check if there are writes to the variable. Later, if there are none, we'll + // reconsider it as globally accessed LUT. + if (!var.is_written_to) + { + var.is_written_to = handler.complete_write_variables_to_block.count(var.self) != 0 || + handler.partial_write_variables_to_block.count(var.self) != 0; + } + // Only consider function local variables here. // If we only have a single function in our CFG, private storage is also fine, // since it behaves like a function local variable. @@ -3755,8 +3862,7 @@ void Compiler::find_function_local_luts(SPIRFunction &entry, const AnalyzeVariab static_constant_expression = var.initializer; // There can be no stores to this variable, we have now proved we have a LUT. - if (handler.complete_write_variables_to_block.count(var.self) != 0 || - handler.partial_write_variables_to_block.count(var.self) != 0) + if (var.is_written_to) continue; } else @@ -4423,11 +4529,9 @@ bool Compiler::ActiveBuiltinHandler::handle(spv::Op opcode, const uint32_t *args for (uint32_t i = 0; i < count; i++) { // Pointers + // PtrAccessChain functions more like a pointer offset. Type remains the same. if (opcode == OpPtrAccessChain && i == 0) - { - type = &compiler.get(type->parent_type); continue; - } // Arrays if (!type->array.empty()) @@ -4615,6 +4719,29 @@ void Compiler::build_function_control_flow_graphs_and_analyze() } } } + + // Find LUTs which are not function local. Only consider this case if the CFG is multi-function, + // otherwise we treat Private as Function trivially. + // Needs to be analyzed from the outside since we have to block the LUT optimization if at least + // one function writes to it. + if (!single_function) + { + for (auto &id : global_variables) + { + auto &var = get(id); + auto &type = get_variable_data_type(var); + + if (is_array(type) && var.storage == StorageClassPrivate && + var.initializer && !var.is_written_to && + ir.ids[var.initializer].get_type() == TypeConstant) + { + get(var.initializer).is_used_as_lut = true; + var.static_expression = var.initializer; + var.statically_assigned = true; + var.remapped_variable = true; + } + } + } } Compiler::CFGBuilder::CFGBuilder(Compiler &compiler_) diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cross.hpp b/libs/bgfx/3rdparty/spirv-cross/spirv_cross.hpp index 2ba6025..e9062b4 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cross.hpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cross.hpp @@ -744,6 +744,8 @@ class Compiler bool function_is_pure(const SPIRFunction &func); bool block_is_pure(const SPIRBlock &block); + bool function_is_control_dependent(const SPIRFunction &func); + bool block_is_control_dependent(const SPIRBlock &block); bool execution_is_branchless(const SPIRBlock &from, const SPIRBlock &to) const; bool execution_is_direct_branch(const SPIRBlock &from, const SPIRBlock &to) const; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.cpp index 679333d..e0cc68c 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.cpp @@ -754,6 +754,10 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP: options->msl.agx_manual_cube_grad_fixup = value != 0; break; + + case SPVC_COMPILER_OPTION_MSL_FORCE_FRAGMENT_WITH_SIDE_EFFECTS_EXECUTION: + options->msl.force_fragment_with_side_effects_execution = value != 0; + break; #endif default: diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.h b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.h index 4736996..acae935 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.h +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_c.h @@ -40,7 +40,7 @@ extern "C" { /* Bumped if ABI or API breaks backwards compatibility. */ #define SPVC_C_API_VERSION_MAJOR 0 /* Bumped if APIs or enumerations are added in a backwards compatible way. */ -#define SPVC_C_API_VERSION_MINOR 59 +#define SPVC_C_API_VERSION_MINOR 60 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -728,6 +728,7 @@ typedef enum spvc_compiler_option SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES = 86 | SPVC_COMPILER_OPTION_MSL_BIT, SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS = 87 | SPVC_COMPILER_OPTION_MSL_BIT, SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP = 88 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_FORCE_FRAGMENT_WITH_SIDE_EFFECTS_EXECUTION = 89 | SPVC_COMPILER_OPTION_MSL_BIT, SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp index 7f35c38..3892248 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_cross_parsed_ir.hpp @@ -169,7 +169,7 @@ class ParsedIR ~LoopLock(); private: - uint32_t *lock; + uint32_t *lock = nullptr; }; // This must be held while iterating over a type ID array. diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp index 0d37ba2..3f13feb 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.cpp @@ -639,7 +639,8 @@ void CompilerGLSL::find_static_extensions() void CompilerGLSL::require_polyfill(Polyfill polyfill, bool relaxed) { - uint32_t &polyfills = (relaxed && options.es) ? required_polyfills_relaxed : required_polyfills; + uint32_t &polyfills = (relaxed && (options.es || options.vulkan_semantics)) ? + required_polyfills_relaxed : required_polyfills; if ((polyfills & polyfill) == 0) { @@ -715,7 +716,7 @@ string CompilerGLSL::compile() if (required_polyfills != 0) emit_polyfills(required_polyfills, false); - if (options.es && required_polyfills_relaxed != 0) + if ((options.es || options.vulkan_semantics) && required_polyfills_relaxed != 0) emit_polyfills(required_polyfills_relaxed, true); emit_function(get(ir.default_entry_point), Bitset()); @@ -2434,7 +2435,7 @@ void CompilerGLSL::emit_buffer_reference_block(uint32_t type_id, bool forward_de else { auto &pointee_type = get_pointee_type(type); - statement(type_to_glsl(pointee_type), " value", type_to_array_glsl(pointee_type), ";"); + statement(type_to_glsl(pointee_type), " value", type_to_array_glsl(pointee_type, 0), ";"); } end_scope_decl(); @@ -2513,7 +2514,7 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var) // It will need to be reset if we have to recompile. preserve_alias_on_reset(var.self); add_resource_name(var.self); - end_scope_decl(to_name(var.self) + type_to_array_glsl(type)); + end_scope_decl(to_name(var.self) + type_to_array_glsl(type, var.self)); statement(""); } @@ -2568,7 +2569,7 @@ const char *CompilerGLSL::to_storage_qualifiers_glsl(const SPIRVariable &var) return var.storage == StorageClassInput ? "in " : "out "; } else if (var.storage == StorageClassUniformConstant || var.storage == StorageClassUniform || - var.storage == StorageClassPushConstant) + var.storage == StorageClassPushConstant || var.storage == StorageClassAtomicCounter) { return "uniform "; } @@ -2780,7 +2781,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var) } add_resource_name(var.self); - end_scope_decl(join(to_name(var.self), type_to_array_glsl(type))); + end_scope_decl(join(to_name(var.self), type_to_array_glsl(type, var.self))); statement(""); } } @@ -3977,7 +3978,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) auto &c = get(var.initializer); for (uint32_t j = 0; j < array_size; j++) exprs.push_back(to_expression(get(c.subconstants[j]).subconstants[i])); - statement("const ", type_to_glsl(array_type), " ", lut_name, type_to_array_glsl(array_type), " = ", + statement("const ", type_to_glsl(array_type), " ", lut_name, type_to_array_glsl(array_type, 0), " = ", type_to_glsl_constructor(array_type), "(", merge(exprs, ", "), ");"); } @@ -4035,7 +4036,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) else if (is_control_point) { auto lut_name = join("_", var.self, "_init"); - statement("const ", type_to_glsl(type), " ", lut_name, type_to_array_glsl(type), + statement("const ", type_to_glsl(type), " ", lut_name, type_to_array_glsl(type, 0), " = ", to_expression(var.initializer), ";"); entry_func.fixup_hooks_in.push_back([&, lut_name]() { statement(to_expression(var.self), "[gl_InvocationID] = ", lut_name, "[gl_InvocationID];"); @@ -4060,7 +4061,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) { auto lut_name = join("_", var.self, "_init"); statement("const ", type_to_glsl(type), " ", lut_name, - type_to_array_glsl(type), " = ", to_expression(var.initializer), ";"); + type_to_array_glsl(type, var.self), " = ", to_expression(var.initializer), ";"); entry_func.fixup_hooks_in.push_back([&, lut_name, is_patch]() { if (is_patch) { @@ -4842,6 +4843,109 @@ void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed) end_scope(); statement(""); } + + if (!relaxed) + { + static const Polyfill polys[3][3] = { + { PolyfillNMin16, PolyfillNMin32, PolyfillNMin64 }, + { PolyfillNMax16, PolyfillNMax32, PolyfillNMax64 }, + { PolyfillNClamp16, PolyfillNClamp32, PolyfillNClamp64 }, + }; + + static const GLSLstd450 glsl_ops[] = { GLSLstd450NMin, GLSLstd450NMax, GLSLstd450NClamp }; + static const char *spv_ops[] = { "spvNMin", "spvNMax", "spvNClamp" }; + bool has_poly = false; + + for (uint32_t i = 0; i < 3; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + if ((polyfills & polys[i][j]) == 0) + continue; + + const char *types[3][4] = { + { "float16_t", "f16vec2", "f16vec3", "f16vec4" }, + { "float", "vec2", "vec3", "vec4" }, + { "double", "dvec2", "dvec3", "dvec4" }, + }; + + for (uint32_t k = 0; k < 4; k++) + { + auto *type = types[j][k]; + + if (i < 2) + { + statement("spirv_instruction(set = \"GLSL.std.450\", id = ", glsl_ops[i], ") ", + type, " ", spv_ops[i], "(", type, ", ", type, ");"); + } + else + { + statement("spirv_instruction(set = \"GLSL.std.450\", id = ", glsl_ops[i], ") ", + type, " ", spv_ops[i], "(", type, ", ", type, ", ", type, ");"); + } + + has_poly = true; + } + } + } + + if (has_poly) + statement(""); + } + else + { + // Mediump intrinsics don't work correctly, so wrap the intrinsic in an outer shell that ensures mediump + // propagation. + + static const Polyfill polys[3][3] = { + { PolyfillNMin16, PolyfillNMin32, PolyfillNMin64 }, + { PolyfillNMax16, PolyfillNMax32, PolyfillNMax64 }, + { PolyfillNClamp16, PolyfillNClamp32, PolyfillNClamp64 }, + }; + + static const char *spv_ops[] = { "spvNMin", "spvNMax", "spvNClamp" }; + + for (uint32_t i = 0; i < 3; i++) + { + for (uint32_t j = 0; j < 3; j++) + { + if ((polyfills & polys[i][j]) == 0) + continue; + + const char *types[3][4] = { + { "float16_t", "f16vec2", "f16vec3", "f16vec4" }, + { "float", "vec2", "vec3", "vec4" }, + { "double", "dvec2", "dvec3", "dvec4" }, + }; + + for (uint32_t k = 0; k < 4; k++) + { + auto *type = types[j][k]; + + if (i < 2) + { + statement("mediump ", type, " ", spv_ops[i], "Relaxed(", + "mediump ", type, " a, mediump ", type, " b)"); + begin_scope(); + statement("mediump ", type, " res = ", spv_ops[i], "(a, b);"); + statement("return res;"); + end_scope(); + statement(""); + } + else + { + statement("mediump ", type, " ", spv_ops[i], "Relaxed(", + "mediump ", type, " a, mediump ", type, " b, mediump ", type, " c)"); + begin_scope(); + statement("mediump ", type, " res = ", spv_ops[i], "(a, b, c);"); + statement("return res;"); + end_scope(); + statement(""); + } + } + } + } + } } // Returns a string representation of the ID, usable as a function arg. @@ -7847,6 +7951,7 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool args.grad_x = grad_x; args.grad_y = grad_y; args.lod = lod; + args.has_array_offsets = coffsets != 0; if (coffsets) args.offset = coffsets; @@ -8864,23 +8969,97 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, case GLSLstd450NMin: case GLSLstd450NMax: { - emit_nminmax_op(result_type, id, args[0], args[1], op); + if (options.vulkan_semantics) + { + require_extension_internal("GL_EXT_spirv_intrinsics"); + bool relaxed = has_decoration(id, DecorationRelaxedPrecision); + Polyfill poly = {}; + switch (get(result_type).width) + { + case 16: + poly = op == GLSLstd450NMin ? PolyfillNMin16 : PolyfillNMax16; + break; + + case 32: + poly = op == GLSLstd450NMin ? PolyfillNMin32 : PolyfillNMax32; + break; + + case 64: + poly = op == GLSLstd450NMin ? PolyfillNMin64 : PolyfillNMax64; + break; + + default: + SPIRV_CROSS_THROW("Invalid bit width for NMin/NMax."); + } + + require_polyfill(poly, relaxed); + + // Function return decorations are broken, so need to do double polyfill. + if (relaxed) + require_polyfill(poly, false); + + const char *op_str; + if (relaxed) + op_str = op == GLSLstd450NMin ? "spvNMinRelaxed" : "spvNMaxRelaxed"; + else + op_str = op == GLSLstd450NMin ? "spvNMin" : "spvNMax"; + + emit_binary_func_op(result_type, id, args[0], args[1], op_str); + } + else + { + emit_nminmax_op(result_type, id, args[0], args[1], op); + } break; } case GLSLstd450NClamp: { - // Make sure we have a unique ID here to avoid aliasing the extra sub-expressions between clamp and NMin sub-op. - // IDs cannot exceed 24 bits, so we can make use of the higher bits for some unique flags. - uint32_t &max_id = extra_sub_expressions[id | EXTRA_SUB_EXPRESSION_TYPE_AUX]; - if (!max_id) - max_id = ir.increase_bound_by(1); + if (options.vulkan_semantics) + { + require_extension_internal("GL_EXT_spirv_intrinsics"); + bool relaxed = has_decoration(id, DecorationRelaxedPrecision); + Polyfill poly = {}; + switch (get(result_type).width) + { + case 16: + poly = PolyfillNClamp16; + break; + + case 32: + poly = PolyfillNClamp32; + break; + + case 64: + poly = PolyfillNClamp64; + break; + + default: + SPIRV_CROSS_THROW("Invalid bit width for NMin/NMax."); + } + + require_polyfill(poly, relaxed); - // Inherit precision qualifiers. - ir.meta[max_id] = ir.meta[id]; + // Function return decorations are broken, so need to do double polyfill. + if (relaxed) + require_polyfill(poly, false); - emit_nminmax_op(result_type, max_id, args[0], args[1], GLSLstd450NMax); - emit_nminmax_op(result_type, id, max_id, args[2], GLSLstd450NMin); + emit_trinary_func_op(result_type, id, args[0], args[1], args[2], relaxed ? "spvNClampRelaxed" : "spvNClamp"); + } + else + { + // Make sure we have a unique ID here to avoid aliasing the extra sub-expressions between clamp and NMin sub-op. + // IDs cannot exceed 24 bits, so we can make use of the higher bits for some unique flags. + uint32_t &max_id = extra_sub_expressions[id | EXTRA_SUB_EXPRESSION_TYPE_AUX]; + if (!max_id) + max_id = ir.increase_bound_by(1); + + // Inherit precision qualifiers. + ir.meta[max_id] = ir.meta[id]; + + emit_nminmax_op(result_type, max_id, args[0], args[1], GLSLstd450NMax); + emit_nminmax_op(result_type, id, max_id, args[2], GLSLstd450NMin); + } break; } @@ -11610,6 +11789,10 @@ uint32_t CompilerGLSL::get_integer_width_for_instruction(const Instruction &inst case OpUGreaterThanEqual: return expression_type(ops[2]).width; + case OpSMulExtended: + case OpUMulExtended: + return get(get(ops[0]).member_types[0]).width; + default: { // We can look at result type which is more robust. @@ -12167,6 +12350,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto &callee = get(func); auto &return_type = get(callee.return_type); bool pure = function_is_pure(callee); + bool control_dependent = function_is_control_dependent(callee); bool callee_has_out_variables = false; bool emit_return_value_as_argument = false; @@ -12198,7 +12382,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) if (emit_return_value_as_argument) { - statement(type_to_glsl(return_type), " ", to_name(id), type_to_array_glsl(return_type), ";"); + statement(type_to_glsl(return_type), " ", to_name(id), type_to_array_glsl(return_type, 0), ";"); arglist.push_back(to_name(id)); } @@ -12260,6 +12444,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) else statement(funexpr, ";"); + if (control_dependent) + register_control_dependent_expression(id); + break; } @@ -15166,7 +15353,7 @@ string CompilerGLSL::variable_decl(const SPIRType &type, const string &name, uin { string type_name = type_to_glsl(type, id); remap_variable_type_name(type, name, type_name); - return join(type_name, " ", name, type_to_array_glsl(type)); + return join(type_name, " ", name, type_to_array_glsl(type, id)); } bool CompilerGLSL::variable_decl_is_remapped_storage(const SPIRVariable &var, StorageClass storage) const @@ -15523,7 +15710,7 @@ string CompilerGLSL::to_array_size(const SPIRType &type, uint32_t index) return ""; } -string CompilerGLSL::type_to_array_glsl(const SPIRType &type) +string CompilerGLSL::type_to_array_glsl(const SPIRType &type, uint32_t) { if (type.pointer && type.storage == StorageClassPhysicalStorageBufferEXT && type.basetype != SPIRType::Struct) { @@ -16087,7 +16274,7 @@ void CompilerGLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret auto &type = get(func.return_type); decl += flags_to_qualifiers_glsl(type, return_flags); decl += type_to_glsl(type); - decl += type_to_array_glsl(type); + decl += type_to_array_glsl(type, 0); decl += " "; if (func.self == ir.default_entry_point) @@ -16747,8 +16934,11 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method bool condition_is_temporary = forced_temporaries.find(block.condition) == end(forced_temporaries); + bool flushes_phi = flush_phi_required(block.self, block.true_block) || + flush_phi_required(block.self, block.false_block); + // This can work! We only did trivial things which could be forwarded in block body! - if (current_count == statement_count && condition_is_temporary) + if (!flushes_phi && current_count == statement_count && condition_is_temporary) { switch (continue_type) { @@ -16827,7 +17017,10 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method bool condition_is_temporary = forced_temporaries.find(child.condition) == end(forced_temporaries); - if (current_count == statement_count && condition_is_temporary) + bool flushes_phi = flush_phi_required(child.self, child.true_block) || + flush_phi_required(child.self, child.false_block); + + if (!flushes_phi && current_count == statement_count && condition_is_temporary) { uint32_t target_block = child.true_block; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp b/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp index 3ce044e..f3e545e 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_glsl.hpp @@ -477,7 +477,7 @@ class CompilerGLSL : public Compiler uint32_t coord = 0, coord_components = 0, dref = 0; uint32_t grad_x = 0, grad_y = 0, lod = 0, offset = 0; uint32_t bias = 0, component = 0, sample = 0, sparse_texel = 0, min_lod = 0; - bool nonuniform_expression = false; + bool nonuniform_expression = false, has_array_offsets = false; }; virtual std::string to_function_args(const TextureFunctionArguments &args, bool *p_forward); @@ -564,8 +564,8 @@ class CompilerGLSL : public Compiler Options options; - virtual std::string type_to_array_glsl( - const SPIRType &type); // Allow Metal to use the array template to make arrays a value type + // Allow Metal to use the array template to make arrays a value type + virtual std::string type_to_array_glsl(const SPIRType &type, uint32_t variable_id); std::string to_array_size(const SPIRType &type, uint32_t index); uint32_t to_array_size_literal(const SPIRType &type, uint32_t index) const; uint32_t to_array_size_literal(const SPIRType &type) const; @@ -933,6 +933,15 @@ class CompilerGLSL : public Compiler PolyfillMatrixInverse2x2 = 1 << 6, PolyfillMatrixInverse3x3 = 1 << 7, PolyfillMatrixInverse4x4 = 1 << 8, + PolyfillNMin16 = 1 << 9, + PolyfillNMin32 = 1 << 10, + PolyfillNMin64 = 1 << 11, + PolyfillNMax16 = 1 << 12, + PolyfillNMax32 = 1 << 13, + PolyfillNMax64 = 1 << 14, + PolyfillNClamp16 = 1 << 15, + PolyfillNClamp32 = 1 << 16, + PolyfillNClamp64 = 1 << 17, }; uint32_t required_polyfills = 0; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_hlsl.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_hlsl.cpp index 9b83493..ac1d262 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_hlsl.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_hlsl.cpp @@ -1002,7 +1002,7 @@ void CompilerHLSL::emit_interface_block_member_in_struct(const SPIRVariable &var statement(to_interpolation_qualifiers(get_member_decoration_bitset(type.self, member_index)), type_to_glsl(mbr_type), - " ", mbr_name, type_to_array_glsl(mbr_type), + " ", mbr_name, type_to_array_glsl(mbr_type, var.self), " : ", semantic, ";"); // Structs and arrays should consume more locations. @@ -2277,7 +2277,7 @@ void CompilerHLSL::emit_resources() // Need out variable since HLSL does not support returning arrays. auto &type = get(type_id); auto type_str = type_to_glsl(type); - auto type_arr_str = type_to_array_glsl(type); + auto type_arr_str = type_to_array_glsl(type, 0); statement("void spvSelectComposite(out ", type_str, " out_value", type_arr_str, ", bool cond, ", type_str, " true_val", type_arr_str, ", ", type_str, " false_val", type_arr_str, ")"); @@ -2679,7 +2679,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) type_name = is_readonly ? "ByteAddressBuffer" : is_interlocked ? "RasterizerOrderedByteAddressBuffer" : "RWByteAddressBuffer"; add_resource_name(var.self); - statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type), + statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";"); } else @@ -2766,7 +2766,7 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) } emit_struct(get(type.self)); - statement("ConstantBuffer<", to_name(type.self), "> ", to_name(var.self), type_to_array_glsl(type), + statement("ConstantBuffer<", to_name(type.self), "> ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";"); } } @@ -2952,7 +2952,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret out_argument += type_to_glsl(type); out_argument += " "; out_argument += "spvReturnValue"; - out_argument += type_to_array_glsl(type); + out_argument += type_to_array_glsl(type, 0); arglist.push_back(std::move(out_argument)); } @@ -2978,7 +2978,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret { // Manufacture automatic sampler arg for SampledImage texture arglist.push_back(join(is_depth_image(arg_type, arg.id) ? "SamplerComparisonState " : "SamplerState ", - to_sampler_expression(arg.id), type_to_array_glsl(arg_type))); + to_sampler_expression(arg.id), type_to_array_glsl(arg_type, arg.id))); } // Hold a pointer to the parameter so we can invalidate the readonly field if needed. @@ -4076,16 +4076,16 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var) is_coherent = has_decoration(var.self, DecorationCoherent); statement(is_coherent ? "globallycoherent " : "", image_type_hlsl_modern(type, var.self), " ", - to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";"); + to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";"); if (type.basetype == SPIRType::SampledImage && type.image.dim != DimBuffer) { // For combined image samplers, also emit a combined image sampler. if (is_depth_image(type, var.self)) - statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type), + statement("SamplerComparisonState ", to_sampler_expression(var.self), type_to_array_glsl(type, var.self), to_resource_binding_sampler(var), ";"); else - statement("SamplerState ", to_sampler_expression(var.self), type_to_array_glsl(type), + statement("SamplerState ", to_sampler_expression(var.self), type_to_array_glsl(type, var.self), to_resource_binding_sampler(var), ";"); } break; @@ -4093,10 +4093,10 @@ void CompilerHLSL::emit_modern_uniform(const SPIRVariable &var) case SPIRType::Sampler: if (comparison_ids.count(var.self)) - statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), + statement("SamplerComparisonState ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";"); else - statement("SamplerState ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";"); + statement("SamplerState ", to_name(var.self), type_to_array_glsl(type, var.self), to_resource_binding(var), ";"); break; default: @@ -4448,6 +4448,18 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count); break; + case GLSLstd450NMin: + CompilerGLSL::emit_glsl_op(result_type, id, GLSLstd450FMin, args, count); + break; + + case GLSLstd450NMax: + CompilerGLSL::emit_glsl_op(result_type, id, GLSLstd450FMax, args, count); + break; + + case GLSLstd450NClamp: + CompilerGLSL::emit_glsl_op(result_type, id, GLSLstd450FClamp, args, count); + break; + default: CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count); break; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_msl.cpp b/libs/bgfx/3rdparty/spirv-cross/spirv_msl.cpp index e73751d..562bb62 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_msl.cpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_msl.cpp @@ -201,13 +201,17 @@ bool CompilerMSL::is_var_runtime_size_array(const SPIRVariable &var) const uint32_t CompilerMSL::get_resource_array_size(const SPIRType &type, uint32_t id) const { uint32_t array_size = to_array_size_literal(type); - if (array_size) + + // If we have argument buffers, we need to honor the ABI by using the correct array size + // from the layout. Only use shader declared size if we're not using argument buffers. + uint32_t desc_set = get_decoration(id, DecorationDescriptorSet); + if (!descriptor_set_is_argument_buffer(desc_set) && array_size) return array_size; - StageSetBinding tuple = { get_entry_point().model, get_decoration(id, DecorationDescriptorSet), + StageSetBinding tuple = { get_entry_point().model, desc_set, get_decoration(id, DecorationBinding) }; auto itr = resource_bindings.find(tuple); - return itr != end(resource_bindings) ? itr->second.first.count : 0; + return itr != end(resource_bindings) ? itr->second.first.count : array_size; } uint32_t CompilerMSL::get_automatic_msl_resource_binding(uint32_t id) const @@ -267,11 +271,14 @@ void CompilerMSL::build_implicit_builtins() active_input_builtins.get(BuiltInInstanceIndex) || active_input_builtins.get(BuiltInBaseInstance)); bool need_local_invocation_index = msl_options.emulate_subgroups && active_input_builtins.get(BuiltInSubgroupId); bool need_workgroup_size = msl_options.emulate_subgroups && active_input_builtins.get(BuiltInNumSubgroups); + bool force_frag_depth_passthrough = + get_execution_model() == ExecutionModelFragment && !uses_explicit_early_fragment_test() && need_subpass_input && + msl_options.enable_frag_depth_builtin && msl_options.input_attachment_is_ds_attachment; if (need_subpass_input || need_sample_pos || need_subgroup_mask || need_vertex_params || need_tesc_params || need_tese_params || need_multiview || need_dispatch_base || need_vertex_base_params || need_grid_params || needs_sample_id || needs_subgroup_invocation_id || needs_subgroup_size || needs_helper_invocation || - has_additional_fixed_sample_mask() || need_local_invocation_index || need_workgroup_size) + has_additional_fixed_sample_mask() || need_local_invocation_index || need_workgroup_size || force_frag_depth_passthrough) { bool has_frag_coord = false; bool has_sample_id = false; @@ -288,6 +295,7 @@ void CompilerMSL::build_implicit_builtins() bool has_helper_invocation = false; bool has_local_invocation_index = false; bool has_workgroup_size = false; + bool has_frag_depth = false; uint32_t workgroup_id_type = 0; ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { @@ -308,6 +316,13 @@ void CompilerMSL::build_implicit_builtins() mark_implicit_builtin(StorageClassOutput, BuiltInSampleMask, var.self); does_shader_write_sample_mask = true; } + + if (force_frag_depth_passthrough && builtin == BuiltInFragDepth) + { + builtin_frag_depth_id = var.self; + mark_implicit_builtin(StorageClassOutput, BuiltInFragDepth, var.self); + has_frag_depth = true; + } } if (var.storage != StorageClassInput) @@ -898,6 +913,36 @@ void CompilerMSL::build_implicit_builtins() builtin_workgroup_size_id = var_id; mark_implicit_builtin(StorageClassInput, BuiltInWorkgroupSize, var_id); } + + if (!has_frag_depth && force_frag_depth_passthrough) + { + uint32_t offset = ir.increase_bound_by(3); + uint32_t type_id = offset; + uint32_t type_ptr_id = offset + 1; + uint32_t var_id = offset + 2; + + // Create gl_FragDepth + SPIRType float_type { OpTypeFloat }; + float_type.basetype = SPIRType::Float; + float_type.width = 32; + float_type.vecsize = 1; + set(type_id, float_type); + + SPIRType float_type_ptr_in = float_type; + float_type_ptr_in.op = spv::OpTypePointer; + float_type_ptr_in.pointer = true; + float_type_ptr_in.pointer_depth++; + float_type_ptr_in.parent_type = type_id; + float_type_ptr_in.storage = StorageClassOutput; + + auto &ptr_in_type = set(type_ptr_id, float_type_ptr_in); + ptr_in_type.self = type_id; + set(var_id, type_ptr_id, StorageClassOutput); + set_decoration(var_id, DecorationBuiltIn, BuiltInFragDepth); + builtin_frag_depth_id = var_id; + mark_implicit_builtin(StorageClassOutput, BuiltInFragDepth, var_id); + active_output_builtins.set(BuiltInFragDepth); + } } if (needs_swizzle_buffer_def) @@ -1314,48 +1359,29 @@ void CompilerMSL::emit_entry_point_declarations() uint32_t arg_id = argument_buffer_ids[desc_set]; uint32_t base_index = dynamic_buffer.second.first; - if (!type.array.empty()) + if (is_array(type)) { - // This is complicated, because we need to support arrays of arrays. - // And it's even worse if the outermost dimension is a runtime array, because now - // all this complicated goop has to go into the shader itself. (FIXME) if (!type.array[type.array.size() - 1]) SPIRV_CROSS_THROW("Runtime arrays with dynamic offsets are not supported yet."); - else - { - is_using_builtin_array = true; - statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name, - type_to_array_glsl(type), " ="); - uint32_t dim = uint32_t(type.array.size()); - uint32_t j = 0; - for (SmallVector indices(type.array.size()); - indices[type.array.size() - 1] < to_array_size_literal(type); j++) - { - while (dim > 0) - { - begin_scope(); - --dim; - } + is_using_builtin_array = true; + statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name, + type_to_array_glsl(type, var_id), " ="); - string arrays; - for (uint32_t i = uint32_t(type.array.size()); i; --i) - arrays += join("[", indices[i - 1], "]"); - statement("(", get_argument_address_space(var), " ", type_to_glsl(type), "* ", - to_restrict(var_id, false), ")((", get_argument_address_space(var), " char* ", - to_restrict(var_id, false), ")", to_name(arg_id), ".", ensure_valid_name(name, "m"), - arrays, " + ", to_name(dynamic_offsets_buffer_id), "[", base_index + j, "]),"); + uint32_t array_size = to_array_size_literal(type); + begin_scope(); - while (++indices[dim] >= to_array_size_literal(type, dim) && dim < type.array.size() - 1) - { - end_scope(","); - indices[dim++] = 0; - } - } - end_scope_decl(); - statement_no_indent(""); - is_using_builtin_array = false; + for (uint32_t i = 0; i < array_size; i++) + { + statement("(", get_argument_address_space(var), " ", type_to_glsl(type), "* ", + to_restrict(var_id, false), ")((", get_argument_address_space(var), " char* ", + to_restrict(var_id, false), ")", to_name(arg_id), ".", ensure_valid_name(name, "m"), + "[", i, "]", " + ", to_name(dynamic_offsets_buffer_id), "[", base_index + i, "]),"); } + + end_scope_decl(); + statement_no_indent(""); + is_using_builtin_array = false; } else { @@ -1373,6 +1399,7 @@ void CompilerMSL::emit_entry_point_declarations() const auto &type = get_variable_data_type(var); const auto &buffer_type = get_variable_element_type(var); const string name = to_name(var.self); + if (is_var_runtime_size_array(var)) { if (msl_options.argument_buffers_tier < Options::ArgumentBuffersTier::Tier2) @@ -1391,10 +1418,10 @@ void CompilerMSL::emit_entry_point_declarations() case SPIRType::Image: case SPIRType::Sampler: case SPIRType::AccelerationStructure: - statement("spvDescriptorArray<", type_to_glsl(buffer_type), "> ", name, " {", resource_name, "};"); + statement("spvDescriptorArray<", type_to_glsl(buffer_type, var.self), "> ", name, " {", resource_name, "};"); break; case SPIRType::SampledImage: - statement("spvDescriptorArray<", type_to_glsl(buffer_type), "> ", name, " {", resource_name, "};"); + statement("spvDescriptorArray<", type_to_glsl(buffer_type, var.self), "> ", name, " {", resource_name, "};"); // Unsupported with argument buffer for now. statement("spvDescriptorArray ", name, "Smplr {", name, "Smplr_};"); break; @@ -1468,7 +1495,7 @@ void CompilerMSL::emit_entry_point_declarations() is_using_builtin_array = true; statement(desc_addr_space, " auto& ", to_restrict(var_id, true), to_name(var_id), " = (", addr_space, " ", type_to_glsl(type), "* ", desc_addr_space, " (&)", - type_to_array_glsl(type), ")", ir.meta[alias_id].decoration.qualified_alias, ";"); + type_to_array_glsl(type, var_id), ")", ir.meta[alias_id].decoration.qualified_alias, ";"); is_using_builtin_array = false; } } @@ -1552,8 +1579,10 @@ string CompilerMSL::compile() if (needs_manual_helper_invocation_updates() && (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) { - string discard_expr = - join(builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), " = true, discard_fragment()"); + string builtin_helper_invocation = builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput); + string discard_expr = join(builtin_helper_invocation, " = true, discard_fragment()"); + if (msl_options.force_fragment_with_side_effects_execution) + discard_expr = join("!", builtin_helper_invocation, " ? (", discard_expr, ") : (void)0"); backend.discard_literal = discard_expr; backend.demote_literal = discard_expr; } @@ -1583,6 +1612,8 @@ string CompilerMSL::compile() add_active_interface_variable(builtin_dispatch_base_id); if (builtin_sample_mask_id) add_active_interface_variable(builtin_sample_mask_id); + if (builtin_frag_depth_id) + add_active_interface_variable(builtin_frag_depth_id); // Create structs to hold input, output and uniform variables. // Do output first to ensure out. is declared at top of entry function. @@ -1702,14 +1733,15 @@ void CompilerMSL::preprocess_op_codes() // Fragment shaders that both write to storage resources and discard fragments // need checks on the writes, to work around Metal allowing these writes despite - // the fragment being dead. - if (msl_options.check_discarded_frag_stores && preproc.uses_discard && - (preproc.uses_buffer_write || preproc.uses_image_write)) + // the fragment being dead. We also require to force Metal to execute fragment + // shaders instead of being prematurely discarded. + if (preproc.uses_discard && (preproc.uses_buffer_write || preproc.uses_image_write)) { - frag_shader_needs_discard_checks = true; - needs_helper_invocation = true; + bool should_enable = (msl_options.check_discarded_frag_stores || msl_options.force_fragment_with_side_effects_execution); + frag_shader_needs_discard_checks |= msl_options.check_discarded_frag_stores; + needs_helper_invocation |= should_enable; // Fragment discard store checks imply manual HelperInvocation updates. - msl_options.manual_helper_invocation_updates = true; + msl_options.manual_helper_invocation_updates |= should_enable; } if (is_intersection_query()) @@ -1880,8 +1912,13 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: { uint32_t base_id = ops[0]; if (global_var_ids.find(base_id) != global_var_ids.end()) + { added_arg_ids.insert(base_id); + if (msl_options.input_attachment_is_ds_attachment && base_id == builtin_frag_depth_id) + writes_to_depth = true; + } + uint32_t rvalue_id = ops[1]; if (global_var_ids.find(rvalue_id) != global_var_ids.end()) added_arg_ids.insert(rvalue_id); @@ -2377,7 +2414,9 @@ uint32_t CompilerMSL::build_extended_vector_type(uint32_t type_id, uint32_t comp if (basetype != SPIRType::Unknown) type->basetype = basetype; type->self = new_type_id; - type->parent_type = type_id; + // We want parent type to point to the scalar type. + type->parent_type = is_scalar(*p_old_type) ? TypeID(p_old_type->self) : p_old_type->parent_type; + assert(is_scalar(get(type->parent_type))); type->array.clear(); type->array_size_literal.clear(); type->pointer = false; @@ -2918,20 +2957,35 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass uint32_t mbr_idx, InterfaceBlockMeta &meta, const string &mbr_name_qual, const string &var_chain_qual, - uint32_t &location, uint32_t &var_mbr_idx) + uint32_t &location, uint32_t &var_mbr_idx, + const Bitset &interpolation_qual) { auto &entry_func = get(ir.default_entry_point); BuiltIn builtin = BuiltInMax; bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); - bool is_flat = - has_member_decoration(var_type.self, mbr_idx, DecorationFlat) || has_decoration(var.self, DecorationFlat); - bool is_noperspective = has_member_decoration(var_type.self, mbr_idx, DecorationNoPerspective) || + bool is_flat = interpolation_qual.get(DecorationFlat) || + has_member_decoration(var_type.self, mbr_idx, DecorationFlat) || + has_decoration(var.self, DecorationFlat); + bool is_noperspective = interpolation_qual.get(DecorationNoPerspective) || + has_member_decoration(var_type.self, mbr_idx, DecorationNoPerspective) || has_decoration(var.self, DecorationNoPerspective); - bool is_centroid = has_member_decoration(var_type.self, mbr_idx, DecorationCentroid) || + bool is_centroid = interpolation_qual.get(DecorationCentroid) || + has_member_decoration(var_type.self, mbr_idx, DecorationCentroid) || has_decoration(var.self, DecorationCentroid); - bool is_sample = - has_member_decoration(var_type.self, mbr_idx, DecorationSample) || has_decoration(var.self, DecorationSample); + bool is_sample = interpolation_qual.get(DecorationSample) || + has_member_decoration(var_type.self, mbr_idx, DecorationSample) || + has_decoration(var.self, DecorationSample); + + Bitset inherited_qual; + if (is_flat) + inherited_qual.set(DecorationFlat); + if (is_noperspective) + inherited_qual.set(DecorationNoPerspective); + if (is_centroid) + inherited_qual.set(DecorationCentroid); + if (is_sample) + inherited_qual.set(DecorationSample); uint32_t mbr_type_id = var_type.member_types[mbr_idx]; auto &mbr_type = get(mbr_type_id); @@ -2995,7 +3049,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_type, sub_mbr_idx, meta, mbr_name, var_chain, - location, var_mbr_idx); + location, var_mbr_idx, inherited_qual); // FIXME: Recursive structs and tessellation breaks here. var_mbr_idx++; } @@ -3482,7 +3536,7 @@ void CompilerMSL::emit_local_masked_variable(const SPIRVariable &masked_var, boo get_entry_point().output_vertices; statement("threadgroup ", type_to_glsl(type), " ", "spvStorage", to_name(masked_var.self), "[", max_num_instances, "]", - type_to_array_glsl(type), ";"); + type_to_array_glsl(type, 0), ";"); // Assign a threadgroup slice to each PrimitiveID. // We assume here that workgroup size is rounded to 32, @@ -3681,7 +3735,7 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, var_type, mbr_idx, meta, mbr_name_qual, var_chain_qual, - location, var_mbr_idx); + location, var_mbr_idx, {}); } else { @@ -4450,13 +4504,13 @@ uint32_t CompilerMSL::ensure_correct_builtin_type(uint32_t type_id, BuiltIn buil ((builtin == BuiltInLayer || builtin == BuiltInViewportIndex || builtin == BuiltInFragStencilRefEXT) && pointee_type.basetype != SPIRType::UInt)) { - uint32_t next_id = ir.increase_bound_by(type_is_pointer(type) ? 2 : 1); + uint32_t next_id = ir.increase_bound_by(is_pointer(type) ? 2 : 1); uint32_t base_type_id = next_id++; auto &base_type = set(base_type_id, OpTypeInt); base_type.basetype = SPIRType::UInt; base_type.width = 32; - if (!type_is_pointer(type)) + if (!is_pointer(type)) return base_type_id; uint32_t ptr_type_id = next_id++; @@ -5338,6 +5392,8 @@ void CompilerMSL::emit_header() // This particular line can be overridden during compilation, so make it a flag and not a pragma line. if (suppress_missing_prototypes) statement("#pragma clang diagnostic ignored \"-Wmissing-prototypes\""); + if (suppress_incompatible_pointer_types_discard_qualifiers) + statement("#pragma clang diagnostic ignored \"-Wincompatible-pointer-types-discards-qualifiers\""); // Disable warning about missing braces for array template to make arrays a value type if (spv_function_implementations.count(SPVFuncImplUnsafeArray) != 0) @@ -5559,9 +5615,8 @@ void CompilerMSL::emit_custom_templates() // otherwise they will cause problems when linked together in a single Metallib. void CompilerMSL::emit_custom_functions() { - for (uint32_t i = kArrayCopyMultidimMax; i >= 2; i--) - if (spv_function_implementations.count(static_cast(SPVFuncImplArrayCopyMultidimBase + i))) - spv_function_implementations.insert(static_cast(SPVFuncImplArrayCopyMultidimBase + i - 1)); + if (spv_function_implementations.count(SPVFuncImplArrayCopyMultidim)) + spv_function_implementations.insert(SPVFuncImplArrayCopy); if (spv_function_implementations.count(SPVFuncImplDynamicImageSampler)) { @@ -5672,11 +5727,7 @@ void CompilerMSL::emit_custom_functions() break; case SPVFuncImplArrayCopy: - case SPVFuncImplArrayOfArrayCopy2Dim: - case SPVFuncImplArrayOfArrayCopy3Dim: - case SPVFuncImplArrayOfArrayCopy4Dim: - case SPVFuncImplArrayOfArrayCopy5Dim: - case SPVFuncImplArrayOfArrayCopy6Dim: + case SPVFuncImplArrayCopyMultidim: { // Unfortunately we cannot template on the address space, so combinatorial explosion it is. static const char *function_name_tags[] = { @@ -5699,36 +5750,19 @@ void CompilerMSL::emit_custom_functions() for (uint32_t variant = 0; variant < 12; variant++) { - uint8_t dimensions = spv_func - SPVFuncImplArrayCopyMultidimBase; - string tmp = "template" : ">"); + statement("inline void spvArrayCopy", function_name_tags[variant], "(", + dst_address_space[variant], " T (&dst)", dim, ", ", + src_address_space[variant], " T (&src)", dim, ")"); begin_scope(); - statement("for (uint i = 0; i < A; i++)"); + statement("for (uint i = 0; i < N; i++)"); begin_scope(); - - if (dimensions == 1) - statement("dst[i] = src[i];"); + if (is_multidim) + statement("spvArrayCopy", function_name_tags[variant], "(dst[i], src[i]);"); else - statement("spvArrayCopy", function_name_tags[variant], dimensions - 1, "(dst[i], src[i]);"); + statement("dst[i] = src[i];"); end_scope(); end_scope(); statement(""); @@ -6229,6 +6263,57 @@ void CompilerMSL::emit_custom_functions() statement(""); break; + case SPVFuncImplGatherConstOffsets: + statement("// Wrapper function that processes a texture gather with a constant offset array."); + statement("template class Tex, " + "typename Toff, typename... Tp>"); + statement("inline vec spvGatherConstOffsets(const thread Tex& t, sampler s, " + "Toff coffsets, component c, Tp... params) METAL_CONST_ARG(c)"); + begin_scope(); + statement("vec rslts[4];"); + statement("for (uint i = 0; i < 4; i++)"); + begin_scope(); + statement("switch (c)"); + begin_scope(); + // Work around texture::gather() requiring its component parameter to be a constant expression + statement("case component::x:"); + statement(" rslts[i] = t.gather(s, spvForward(params)..., coffsets[i], component::x);"); + statement(" break;"); + statement("case component::y:"); + statement(" rslts[i] = t.gather(s, spvForward(params)..., coffsets[i], component::y);"); + statement(" break;"); + statement("case component::z:"); + statement(" rslts[i] = t.gather(s, spvForward(params)..., coffsets[i], component::z);"); + statement(" break;"); + statement("case component::w:"); + statement(" rslts[i] = t.gather(s, spvForward(params)..., coffsets[i], component::w);"); + statement(" break;"); + end_scope(); + end_scope(); + // Pull all values from the i0j0 component of each gather footprint + statement("return vec(rslts[0].w, rslts[1].w, rslts[2].w, rslts[3].w);"); + end_scope(); + statement(""); + break; + + case SPVFuncImplGatherCompareConstOffsets: + statement("// Wrapper function that processes a texture gather with a constant offset array."); + statement("template class Tex, " + "typename Toff, typename... Tp>"); + statement("inline vec spvGatherCompareConstOffsets(const thread Tex& t, sampler s, " + "Toff coffsets, Tp... params)"); + begin_scope(); + statement("vec rslts[4];"); + statement("for (uint i = 0; i < 4; i++)"); + begin_scope(); + statement(" rslts[i] = t.gather_compare(s, spvForward(params)..., coffsets[i]);"); + end_scope(); + // Pull all values from the i0j0 component of each gather footprint + statement("return vec(rslts[0].w, rslts[1].w, rslts[2].w, rslts[3].w);"); + end_scope(); + statement(""); + break; + case SPVFuncImplSubgroupBroadcast: // Metal doesn't allow broadcasting boolean values directly, but we can work around that by broadcasting // them as integers. @@ -7421,14 +7506,14 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("struct spvDescriptorArray"); begin_scope(); - statement("spvDescriptorArray(const device spvDescriptor* ptr) : ptr(ptr)"); + statement("spvDescriptorArray(const device spvDescriptor* ptr) : ptr(&ptr->value)"); begin_scope(); end_scope(); statement("const device T& operator [] (size_t i) const"); begin_scope(); - statement("return ptr[i].value;"); + statement("return ptr[i];"); end_scope(); - statement("const device spvDescriptor* ptr;"); + statement("const device T* ptr;"); end_scope_decl(); statement(""); } @@ -7487,6 +7572,23 @@ void CompilerMSL::emit_custom_functions() statement(""); break; + case SPVFuncImplImageFence: + statement("template "); + statement("void spvImageFence(ImageT img) { img.fence(); }"); + statement(""); + break; + + case SPVFuncImplTextureCast: + statement("template "); + statement("T spvTextureCast(U img)"); + begin_scope(); + // MSL complains if you try to cast the texture itself, but casting the reference type is ... ok? *shrug* + // Gotta go what you gotta do I suppose. + statement("return reinterpret_cast(img);"); + end_scope(); + statement(""); + break; + default: break; } @@ -8963,7 +9065,12 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) // Metal requires explicit fences to break up RAW hazards, even within the same shader invocation if (msl_options.readwrite_texture_fences && p_var && !has_decoration(p_var->self, DecorationNonWritable)) - statement(to_expression(img_id), ".fence();"); + { + add_spv_func_and_recompile(SPVFuncImplImageFence); + // Need to wrap this with a value type, + // since the Metal headers are broken and do not consider case when the image is a reference. + statement("spvImageFence(", to_expression(img_id), ");"); + } emit_texture_op(instruction, false); break; @@ -9412,32 +9519,12 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t op1 = ops[3]; auto &type = get(result_type); auto input_type = opcode == OpSMulExtended ? int_type : uint_type; - auto &output_type = get_type(result_type); string cast_op0, cast_op1; - auto expected_type = binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, false); - + binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, false); emit_uninitialized_temporary_expression(result_type, result_id); - - string mullo_expr, mulhi_expr; - mullo_expr = join(cast_op0, " * ", cast_op1); - mulhi_expr = join("mulhi(", cast_op0, ", ", cast_op1, ")"); - - auto &low_type = get_type(output_type.member_types[0]); - auto &high_type = get_type(output_type.member_types[1]); - if (low_type.basetype != input_type) - { - expected_type.basetype = input_type; - mullo_expr = join(bitcast_glsl_op(low_type, expected_type), "(", mullo_expr, ")"); - } - if (high_type.basetype != input_type) - { - expected_type.basetype = input_type; - mulhi_expr = join(bitcast_glsl_op(high_type, expected_type), "(", mulhi_expr, ")"); - } - - statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", mullo_expr, ";"); - statement(to_expression(result_id), ".", to_member_name(type, 1), " = ", mulhi_expr, ";"); + statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", cast_op0, " * ", cast_op1, ";"); + statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(", cast_op0, ", ", cast_op1, ");"); break; } @@ -10004,15 +10091,7 @@ bool CompilerMSL::emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rh // we cannot easily detect this case ahead of time since it's // context dependent. We might have to force a recompile here // if this is the only use of array copies in our shader. - if (type.array.size() > 1) - { - if (type.array.size() > kArrayCopyMultidimMax) - SPIRV_CROSS_THROW("Cannot support this many dimensions for arrays of arrays."); - auto func = static_cast(SPVFuncImplArrayCopyMultidimBase + type.array.size()); - add_spv_func_and_recompile(func); - } - else - add_spv_func_and_recompile(SPVFuncImplArrayCopy); + add_spv_func_and_recompile(type.array.size() > 1 ? SPVFuncImplArrayCopyMultidim : SPVFuncImplArrayCopy); const char *tag = nullptr; if (lhs_is_thread_storage && is_constant) @@ -10044,13 +10123,13 @@ bool CompilerMSL::emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rh // Pass internal array of spvUnsafeArray<> into wrapper functions if (lhs_is_array_template && rhs_is_array_template && !msl_options.force_native_arrays) - statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ".elements, ", to_expression(rhs_id), ".elements);"); + statement("spvArrayCopy", tag, "(", lhs, ".elements, ", to_expression(rhs_id), ".elements);"); if (lhs_is_array_template && !msl_options.force_native_arrays) - statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ".elements, ", to_expression(rhs_id), ");"); + statement("spvArrayCopy", tag, "(", lhs, ".elements, ", to_expression(rhs_id), ");"); else if (rhs_is_array_template && !msl_options.force_native_arrays) - statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ", ", to_expression(rhs_id), ".elements);"); + statement("spvArrayCopy", tag, "(", lhs, ", ", to_expression(rhs_id), ".elements);"); else - statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ", ", to_expression(rhs_id), ");"); + statement("spvArrayCopy", tag, "(", lhs, ", ", to_expression(rhs_id), ");"); } return true; @@ -10127,7 +10206,8 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, { string exp; - auto &type = get_pointee_type(expression_type(obj)); + auto &ptr_type = expression_type(obj); + auto &type = get_pointee_type(ptr_type); auto expected_type = type.basetype; if (opcode == OpAtomicUMax || opcode == OpAtomicUMin) expected_type = to_unsigned_basetype(type.width); @@ -10147,15 +10227,13 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, remapped_type.basetype = expected_type; auto *var = maybe_get_backing_variable(obj); - if (!var) - SPIRV_CROSS_THROW("No backing variable for atomic operation."); - const auto &res_type = get(var->basetype); + const auto *res_type = var ? &get(var->basetype) : nullptr; + assert(type.storage != StorageClassImage || res_type); bool is_atomic_compare_exchange_strong = op1_is_pointer && op1; bool check_discard = opcode != OpAtomicLoad && needs_frag_discard_checks() && - ((res_type.storage == StorageClassUniformConstant && res_type.basetype == SPIRType::Image) || - var->storage == StorageClassStorageBuffer || var->storage == StorageClassUniform); + ptr_type.storage != StorageClassWorkgroup; // Even compare exchange atomics are vec4 on metal for ... reasons :v uint32_t vec4_temporary_id = 0; @@ -10196,26 +10274,86 @@ void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, // Will only be false if we're in "force recompile later" mode. if (split_index != string::npos) - exp += join(obj_expression.substr(0, split_index), ".", op, "(", obj_expression.substr(split_index + 1)); + { + auto coord = obj_expression.substr(split_index + 1); + auto image_expr = obj_expression.substr(0, split_index); + + // Handle problem cases with sign where we need signed min/max on a uint image for example. + // It seems to work to cast the texture type itself, even if it is probably wildly outside of spec, + // but SPIR-V requires this to work. + if ((opcode == OpAtomicUMax || opcode == OpAtomicUMin || + opcode == OpAtomicSMax || opcode == OpAtomicSMin) && + type.basetype != expected_type) + { + auto *backing_var = maybe_get_backing_variable(obj); + if (backing_var) + { + add_spv_func_and_recompile(SPVFuncImplTextureCast); + + const auto *backing_type = &get(backing_var->basetype); + while (backing_type->op != OpTypeImage) + backing_type = &get(backing_type->parent_type); + + auto img_type = *backing_type; + auto tmp_type = type; + tmp_type.basetype = expected_type; + img_type.image.type = ir.increase_bound_by(1); + set(img_type.image.type, tmp_type); + + image_expr = join("spvTextureCast<", type_to_glsl(img_type, obj), ">(", image_expr, ")"); + } + } + + exp += join(image_expr, ".", op, "("); + if (ptr_type.storage == StorageClassImage && res_type->image.arrayed) + { + switch (res_type->image.dim) + { + case Dim1D: + if (msl_options.texture_1D_as_2D) + exp += join("uint2(", coord, ".x, 0), ", coord, ".y"); + else + exp += join(coord, ".x, ", coord, ".y"); + + break; + case Dim2D: + exp += join(coord, ".xy, ", coord, ".z"); + break; + default: + SPIRV_CROSS_THROW("Cannot do atomics on Cube textures."); + } + } + else if (ptr_type.storage == StorageClassImage && res_type->image.dim == Dim1D && msl_options.texture_1D_as_2D) + exp += join("uint2(", coord, ", 0)"); + else + exp += coord; + } else + { exp += obj_expression; + } } else { exp += string(op) + "_explicit("; exp += "("; // Emulate texture2D atomic operations - if (res_type.storage == StorageClassUniformConstant && res_type.basetype == SPIRType::Image) + if (ptr_type.storage == StorageClassImage) { auto &flags = ir.get_decoration_bitset(var->self); if (decoration_flags_signal_volatile(flags)) exp += "volatile "; exp += "device"; } - else + else if (var && ptr_type.storage != StorageClassPhysicalStorageBuffer) { exp += get_argument_address_space(*var); } + else + { + // Fallback scenario, could happen for raw pointers. + exp += ptr_type.storage == StorageClassWorkgroup ? "threadgroup" : "device"; + } exp += " atomic_"; // For signed and unsigned min/max, we can signal this through the pointer type. @@ -10354,19 +10492,54 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, op = get_remapped_glsl_op(op); + auto &restype = get(result_type); + switch (op) { case GLSLstd450Sinh: - emit_unary_func_op(result_type, id, args[0], "fast::sinh"); + if (restype.basetype == SPIRType::Half) + { + // MSL does not have overload for half. Force-cast back to half. + auto expr = join("half(fast::sinh(", to_unpacked_expression(args[0]), "))"); + emit_op(result_type, id, expr, should_forward(args[0])); + inherit_expression_dependencies(id, args[0]); + } + else + 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"); + if (restype.basetype == SPIRType::Half) + { + // MSL does not have overload for half. Force-cast back to half. + auto expr = join("half(fast::cosh(", to_unpacked_expression(args[0]), "))"); + emit_op(result_type, id, expr, should_forward(args[0])); + inherit_expression_dependencies(id, args[0]); + } + else + 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"); + if (restype.basetype == SPIRType::Half) + { + // MSL does not have overload for half. Force-cast back to half. + auto expr = join("half(fast::tanh(", to_unpacked_expression(args[0]), "))"); + emit_op(result_type, id, expr, should_forward(args[0])); + inherit_expression_dependencies(id, args[0]); + } + else + 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], "precise::atan2"); + if (restype.basetype == SPIRType::Half) + { + // MSL does not have overload for half. Force-cast back to half. + auto expr = join("half(fast::atan2(", to_unpacked_expression(args[0]), ", ", to_unpacked_expression(args[1]), "))"); + emit_op(result_type, id, expr, should_forward(args[0]) && should_forward(args[1])); + inherit_expression_dependencies(id, args[0]); + inherit_expression_dependencies(id, args[1]); + } + else + 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"); @@ -10762,7 +10935,7 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &) decl += "thread "; decl += type_to_glsl(type); decl += " (&spvReturnValue)"; - decl += type_to_array_glsl(type); + decl += type_to_array_glsl(type, 0); if (!func.arguments.empty()) decl += ", "; } @@ -10886,8 +11059,7 @@ string CompilerMSL::to_function_name(const TextureFunctionNameArguments &args) is_dynamic_img_sampler = has_extended_decoration(var->self, SPIRVCrossDecorationDynamicImageSampler); } - // Special-case gather. We have to alter the component being looked up - // in the swizzle case. + // Special-case gather. We have to alter the component being looked up in the swizzle case. if (msl_options.swizzle_texture_samples && args.base.is_gather && !is_dynamic_img_sampler && (!constexpr_sampler || !constexpr_sampler->ycbcr_conversion_enable)) { @@ -10896,6 +11068,16 @@ string CompilerMSL::to_function_name(const TextureFunctionNameArguments &args) return is_compare ? "spvGatherCompareSwizzle" : "spvGatherSwizzle"; } + // Special-case gather with an array of offsets. We have to lower into 4 separate gathers. + if (args.has_array_offsets && !is_dynamic_img_sampler && + (!constexpr_sampler || !constexpr_sampler->ycbcr_conversion_enable)) + { + bool is_compare = comparison_ids.count(img); + add_spv_func_and_recompile(is_compare ? SPVFuncImplGatherCompareConstOffsets : SPVFuncImplGatherConstOffsets); + add_spv_func_and_recompile(SPVFuncImplForwardArgs); + return is_compare ? "spvGatherCompareConstOffsets" : "spvGatherConstOffsets"; + } + auto *combined = maybe_get(img); // Texture reference @@ -11076,6 +11258,10 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool farg_str += to_expression(combined ? combined->image : img); } + // Gathers with constant offsets call a special function, so include the texture. + if (args.has_array_offsets) + farg_str += to_expression(img); + // Sampler reference if (!args.base.is_fetch) { @@ -11092,11 +11278,17 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool used_swizzle_buffer = true; } - // Swizzled gather puts the component before the other args, to allow template - // deduction to work. - if (args.component && msl_options.swizzle_texture_samples) + // Const offsets gather puts the const offsets before the other args. + if (args.has_array_offsets) { - forward = should_forward(args.component); + forward = forward && should_forward(args.offset); + farg_str += ", " + to_expression(args.offset); + } + + // Const offsets gather or swizzled gather puts the component before the other args. + if (args.component && (args.has_array_offsets || msl_options.swizzle_texture_samples)) + { + forward = forward && should_forward(args.component); farg_str += ", " + to_component_argument(args.component); } } @@ -11507,7 +11699,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool // Add offsets string offset_expr; const SPIRType *offset_type = nullptr; - if (args.offset && !args.base.is_fetch) + if (args.offset && !args.base.is_fetch && !args.has_array_offsets) { forward = forward && should_forward(args.offset); offset_expr = to_expression(args.offset); @@ -11546,7 +11738,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool } } - if (args.component) + if (args.component && !args.has_array_offsets) { // If 2D has gather component, ensure it also has an offset arg if (imgtype.image.dim == Dim2D && offset_expr.empty()) @@ -12226,7 +12418,7 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_ variable_storage_requires_stage_io(StorageClassInput))); if (is_ib_in_out && is_member_builtin(type, index, &builtin)) is_using_builtin_array = true; - array_type = type_to_array_glsl(physical_type); + array_type = type_to_array_glsl(physical_type, orig_id); } if (orig_id) @@ -12260,7 +12452,11 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_ else decl_type = type_to_glsl(*declared_type, orig_id, true); - auto result = join(pack_pfx, decl_type, " ", qualifier, + const char *overlapping_binding_tag = + has_extended_member_decoration(type.self, index, SPIRVCrossDecorationOverlappingBinding) ? + "// Overlapping binding: " : ""; + + auto result = join(overlapping_binding_tag, pack_pfx, decl_type, " ", qualifier, to_member_name(type, index), member_attribute_qualifier(type, index), array_type, ";"); is_using_builtin_array = false; @@ -12792,14 +12988,14 @@ uint32_t CompilerMSL::get_or_allocate_builtin_output_member_location(spv::BuiltI string CompilerMSL::func_type_decl(SPIRType &type) { // The regular function return type. If not processing the entry point function, that's all we need - string return_type = type_to_glsl(type) + type_to_array_glsl(type); + string return_type = type_to_glsl(type) + type_to_array_glsl(type, 0); if (!processing_entry_point) return return_type; // If an outgoing interface block has been defined, and it should be returned, override the entry point return type bool ep_should_return_output = !get_is_rasterization_disabled(); if (stage_out_var_id && ep_should_return_output) - return_type = type_to_glsl(get_stage_out_struct_type()) + type_to_array_glsl(type); + return_type = type_to_glsl(get_stage_out_struct_type()) + type_to_array_glsl(type, 0); // Prepend a entry type, based on the execution model string entry_type; @@ -13451,7 +13647,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) struct Resource { SPIRVariable *var; - SPIRVariable *descriptor_alias; + SPIRVariable *discrete_descriptor_alias; string name; SPIRType::BaseType basetype; uint32_t index; @@ -13486,9 +13682,12 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) } } - // Handle descriptor aliasing. We can handle aliasing of buffers by casting pointers, - // but not for typed resources. - SPIRVariable *descriptor_alias = nullptr; + // Handle descriptor aliasing of simple discrete cases. + // We can handle aliasing of buffers by casting pointers. + // The amount of aliasing we can perform for discrete descriptors is very limited. + // For fully mutable-style aliasing, we need argument buffers where we can exploit the fact + // that descriptors are all 8 bytes. + SPIRVariable *discrete_descriptor_alias = nullptr; if (var.storage == StorageClassUniform || var.storage == StorageClassStorageBuffer) { for (auto &resource : resources) @@ -13501,10 +13700,10 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) (resource.var->storage == StorageClassUniform || resource.var->storage == StorageClassStorageBuffer)) { - descriptor_alias = resource.var; + discrete_descriptor_alias = resource.var; // Self-reference marks that we should declare the resource, // and it's being used as an alias (so we can emit void* instead). - resource.descriptor_alias = resource.var; + resource.discrete_descriptor_alias = resource.var; // Need to promote interlocked usage so that the primary declaration is correct. if (interlocked_resources.count(var_id)) interlocked_resources.insert(resource.var->self); @@ -13541,13 +13740,13 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) entry_point_bindings.push_back(&var); for (uint32_t i = 0; i < plane_count; i++) - resources.push_back({ &var, descriptor_alias, to_name(var_id), SPIRType::Image, - get_metal_resource_index(var, SPIRType::Image, i), i, secondary_index }); + resources.push_back({&var, discrete_descriptor_alias, to_name(var_id), SPIRType::Image, + get_metal_resource_index(var, SPIRType::Image, i), i, secondary_index }); if (type.image.dim != DimBuffer && !constexpr_sampler) { - resources.push_back({ &var, descriptor_alias, to_sampler_expression(var_id), SPIRType::Sampler, - get_metal_resource_index(var, SPIRType::Sampler), 0, 0 }); + resources.push_back({&var, discrete_descriptor_alias, to_sampler_expression(var_id), SPIRType::Sampler, + get_metal_resource_index(var, SPIRType::Sampler), 0, 0 }); } } else if (!constexpr_sampler) @@ -13557,12 +13756,12 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) // Don't allocate resource indices for aliases. uint32_t resource_index = ~0u; - if (!descriptor_alias) + if (!discrete_descriptor_alias) resource_index = get_metal_resource_index(var, type.basetype); entry_point_bindings.push_back(&var); - resources.push_back({ &var, descriptor_alias, to_name(var_id), type.basetype, - resource_index, 0, secondary_index }); + resources.push_back({&var, discrete_descriptor_alias, to_name(var_id), type.basetype, + resource_index, 0, secondary_index }); } } }); @@ -13586,9 +13785,9 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) if (m.members.size() == 0) break; - if (r.descriptor_alias) + if (r.discrete_descriptor_alias) { - if (r.var == r.descriptor_alias) + if (r.var == r.discrete_descriptor_alias) { auto primary_name = join("spvBufferAliasSet", get_decoration(var_id, DecorationDescriptorSet), @@ -14362,16 +14561,33 @@ void CompilerMSL::fix_up_shader_inputs_outputs() } } else if (var.storage == StorageClassOutput && get_execution_model() == ExecutionModelFragment && - is_builtin_variable(var) && active_output_builtins.get(bi_type) && - bi_type == BuiltInSampleMask && has_additional_fixed_sample_mask()) + is_builtin_variable(var) && active_output_builtins.get(bi_type)) { - // If the additional fixed sample mask was set, we need to adjust the sample_mask - // output to reflect that. If the shader outputs the sample_mask itself too, we need - // to AND the two masks to get the final one. - string op_str = does_shader_write_sample_mask ? " &= " : " = "; - entry_func.fixup_hooks_out.push_back([=]() { - statement(to_expression(builtin_sample_mask_id), op_str, additional_fixed_sample_mask_str(), ";"); - }); + switch (bi_type) + { + case BuiltInSampleMask: + if (has_additional_fixed_sample_mask()) + { + // If the additional fixed sample mask was set, we need to adjust the sample_mask + // output to reflect that. If the shader outputs the sample_mask itself too, we need + // to AND the two masks to get the final one. + string op_str = does_shader_write_sample_mask ? " &= " : " = "; + entry_func.fixup_hooks_out.push_back([=]() { + statement(to_expression(builtin_sample_mask_id), op_str, additional_fixed_sample_mask_str(), ";"); + }); + } + break; + case BuiltInFragDepth: + if (msl_options.input_attachment_is_ds_attachment && !writes_to_depth) + { + entry_func.fixup_hooks_out.push_back([=]() { + statement(to_expression(builtin_frag_depth_id), " = ", to_expression(builtin_frag_coord_id), ".z;"); + }); + } + break; + default: + break; + } } }); } @@ -14499,24 +14715,6 @@ bool CompilerMSL::type_is_msl_framebuffer_fetch(const SPIRType &type) const msl_options.use_framebuffer_fetch_subpasses; } -bool CompilerMSL::type_is_pointer(const SPIRType &type) const -{ - if (!type.pointer) - return false; - auto &parent_type = get(type.parent_type); - // Safeguards when we forget to set pointer_depth (there is an assert for it in type_to_glsl), - // but the extra check shouldn't hurt. - return (type.pointer_depth > parent_type.pointer_depth) || !parent_type.pointer; -} - -bool CompilerMSL::type_is_pointer_to_pointer(const SPIRType &type) const -{ - if (!type.pointer) - return false; - auto &parent_type = get(type.parent_type); - return type.pointer_depth > parent_type.pointer_depth && type_is_pointer(parent_type); -} - const char *CompilerMSL::descriptor_address_space(uint32_t id, StorageClass storage, const char *plain_address_space) const { if (msl_options.argument_buffers) @@ -14646,7 +14844,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) else { // The type is a pointer type we need to emit cv_qualifier late. - if (type_is_pointer(type)) + if (is_pointer(type)) { decl = type_to_glsl(type, arg.id); if (*cv_qualifier != '\0') @@ -14681,7 +14879,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } decl += to_expression(name_id); decl += ")"; - decl += type_to_array_glsl(type); + decl += type_to_array_glsl(type, name_id); } else { @@ -14732,7 +14930,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } else { - auto array_size_decl = type_to_array_glsl(type); + auto array_size_decl = type_to_array_glsl(type, name_id); if (array_size_decl.empty()) decl += "& "; else @@ -14760,7 +14958,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) // for the reference has to go before the '&', but after the '*'. if (!address_space.empty()) { - if (type_is_pointer(type)) + if (is_pointer(type)) { if (*cv_qualifier == '\0') decl += ' '; @@ -15008,6 +15206,7 @@ const std::unordered_set &CompilerMSL::get_illegal_func_names() "fmin3", "fmax3", "divide", + "median3", "VARIABLE_TRACEPOINT", "STATIC_DATA_TRACEPOINT", "STATIC_DATA_TRACEPOINT_V", @@ -15277,13 +15476,13 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member) // We could always go this route, but it makes the code unnatural. // Prefer emitting thread T *foo over T thread* foo since it's more readable, // but we'll have to emit thread T * thread * T constant bar; for example. - if (type_is_pointer_to_pointer(type)) + if (is_pointer(type) && is_pointer(*p_parent_type)) type_name = join(type_to_glsl(*p_parent_type, id), " ", type_address_space, " "); else { // Since this is not a pointer-to-pointer, ensure we've dug down to the base type. // Some situations chain pointers even though they are not formally pointers-of-pointers. - while (type_is_pointer(*p_parent_type)) + while (is_pointer(*p_parent_type)) p_parent_type = &get(p_parent_type->parent_type); // If we're emitting BDA, just use the templated type. @@ -15472,7 +15671,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) return type_to_glsl(type, id, false); } -string CompilerMSL::type_to_array_glsl(const SPIRType &type) +string CompilerMSL::type_to_array_glsl(const SPIRType &type, uint32_t variable_id) { // Allow Metal to use the array template to make arrays a value type switch (type.basetype) @@ -15480,11 +15679,20 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type) case SPIRType::AtomicCounter: case SPIRType::ControlPointArray: case SPIRType::RayQuery: - return CompilerGLSL::type_to_array_glsl(type); + return CompilerGLSL::type_to_array_glsl(type, variable_id); default: if (type_is_array_of_pointers(type) || using_builtin_array()) - return CompilerGLSL::type_to_array_glsl(type); + { + const SPIRVariable *var = variable_id ? &get(variable_id) : nullptr; + if (var && (var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer) && + is_array(get_variable_data_type(*var))) + { + return join("[", get_resource_array_size(type, variable_id), "]"); + } + else + return CompilerGLSL::type_to_array_glsl(type, variable_id); + } else return ""; } @@ -15650,8 +15858,8 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id, bool memb string img_type_name; - // Bypass pointers because we need the real image struct - auto &img_type = get(type.self).image; + auto &img_type = type.image; + if (is_depth_image(type, id)) { switch (img_type.dim) @@ -16830,7 +17038,7 @@ uint32_t CompilerMSL::get_declared_type_size_msl(const SPIRType &type, bool is_p // stopping when we hit a pointer that is not also an array. int32_t dim_idx = (int32_t)type.array.size() - 1; auto *p_type = &type; - while (!type_is_pointer(*p_type) && dim_idx >= 0) + while (!is_pointer(*p_type) && dim_idx >= 0) { type_size *= to_array_size_literal(*p_type, dim_idx); p_type = &get(p_type->parent_type); @@ -17836,6 +18044,101 @@ bool CompilerMSL::is_supported_argument_buffer_type(const SPIRType &type) const return is_supported_type && !type_is_msl_framebuffer_fetch(type); } +void CompilerMSL::emit_argument_buffer_aliased_descriptor(const SPIRVariable &aliased_var, + const SPIRVariable &base_var) +{ + // To deal with buffer <-> image aliasing, we need to perform an unholy UB ritual. + // A texture type in Metal 3.0 is a pointer. However, we cannot simply cast a pointer to texture. + // What we *can* do is to cast pointer-to-pointer to pointer-to-texture. + + // We need to explicitly reach into the descriptor buffer lvalue, not any spvDescriptorArray wrapper. + auto *var_meta = ir.find_meta(base_var.self); + bool old_explicit_qualifier = var_meta && var_meta->decoration.qualified_alias_explicit_override; + if (var_meta) + var_meta->decoration.qualified_alias_explicit_override = false; + auto unqualified_name = to_name(base_var.self, false); + if (var_meta) + var_meta->decoration.qualified_alias_explicit_override = old_explicit_qualifier; + + // For non-arrayed buffers, we have already performed a de-reference. + // We need a proper lvalue to cast, so strip away the de-reference. + if (unqualified_name.size() > 2 && unqualified_name[0] == '(' && unqualified_name[1] == '*') + { + unqualified_name.erase(unqualified_name.begin(), unqualified_name.begin() + 2); + unqualified_name.pop_back(); + } + + string name; + + auto &var_type = get(aliased_var.basetype); + auto &data_type = get_variable_data_type(aliased_var); + string descriptor_storage = descriptor_address_space(aliased_var.self, aliased_var.storage, ""); + + if (aliased_var.storage == StorageClassUniformConstant) + { + if (is_var_runtime_size_array(aliased_var)) + { + // This becomes a plain pointer to spvDescriptor. + name = join("reinterpret_cast<", descriptor_storage, " ", + type_to_glsl(get_variable_data_type(aliased_var), aliased_var.self, true), ">(&", + unqualified_name, ")"); + } + else + { + name = join("reinterpret_cast<", descriptor_storage, " ", + type_to_glsl(get_variable_data_type(aliased_var), aliased_var.self, true), " &>(", + unqualified_name, ");"); + } + } + else + { + // Buffer types. + bool old_is_using_builtin_array = is_using_builtin_array; + is_using_builtin_array = true; + + bool needs_post_cast_deref = !is_array(data_type); + string ref_type = needs_post_cast_deref ? "&" : join("(&)", type_to_array_glsl(var_type, aliased_var.self)); + + if (is_var_runtime_size_array(aliased_var)) + { + name = join("reinterpret_cast<", + type_to_glsl(var_type, aliased_var.self, true), " ", descriptor_storage, " *>(&", + unqualified_name, ")"); + } + else + { + name = join(needs_post_cast_deref ? "*" : "", "reinterpret_cast<", + type_to_glsl(var_type, aliased_var.self, true), " ", descriptor_storage, " ", + ref_type, + ">(", unqualified_name, ");"); + } + + if (needs_post_cast_deref) + descriptor_storage = get_type_address_space(var_type, aliased_var.self, false); + + // These kinds of ridiculous casts trigger warnings in compiler. Just ignore them. + if (!suppress_incompatible_pointer_types_discard_qualifiers) + { + suppress_incompatible_pointer_types_discard_qualifiers = true; + force_recompile_guarantee_forward_progress(); + } + + is_using_builtin_array = old_is_using_builtin_array; + } + + if (!is_var_runtime_size_array(aliased_var)) + { + // Lower to temporary, so drop the qualification. + set_qualified_name(aliased_var.self, ""); + statement(descriptor_storage, " auto &", to_name(aliased_var.self), " = ", name); + } + else + { + // This will get wrapped in a separate temporary when a spvDescriptorArray wrapper is emitted. + set_qualified_name(aliased_var.self, name); + } +} + void CompilerMSL::analyze_argument_buffers() { // Gather all used resources and sort them out into argument buffers. @@ -17852,11 +18155,11 @@ void CompilerMSL::analyze_argument_buffers() struct Resource { SPIRVariable *var; - SPIRVariable *descriptor_alias; string name; SPIRType::BaseType basetype; uint32_t index; uint32_t plane; + uint32_t overlapping_var_id; }; SmallVector resources_in_set[kMaxArgumentBuffers]; SmallVector inline_block_vars; @@ -17892,32 +18195,6 @@ void CompilerMSL::analyze_argument_buffers() } } - // Handle descriptor aliasing as well as we can. - // We can handle aliasing of buffers by casting pointers, but not for typed resources. - // Inline UBOs cannot be handled since it's not a pointer, but inline data. - SPIRVariable *descriptor_alias = nullptr; - if (var.storage == StorageClassUniform || var.storage == StorageClassStorageBuffer) - { - for (auto &resource : resources_in_set[desc_set]) - { - if (get_decoration(resource.var->self, DecorationBinding) == - get_decoration(var_id, DecorationBinding) && - resource.basetype == SPIRType::Struct && type.basetype == SPIRType::Struct && - (resource.var->storage == StorageClassUniform || - resource.var->storage == StorageClassStorageBuffer)) - { - descriptor_alias = resource.var; - // Self-reference marks that we should declare the resource, - // and it's being used as an alias (so we can emit void* instead). - resource.descriptor_alias = resource.var; - // Need to promote interlocked usage so that the primary declaration is correct. - if (interlocked_resources.count(var_id)) - interlocked_resources.insert(resource.var->self); - break; - } - } - } - uint32_t binding = get_decoration(var_id, DecorationBinding); if (type.basetype == SPIRType::SampledImage) { @@ -17931,14 +18208,14 @@ void CompilerMSL::analyze_argument_buffers() { uint32_t image_resource_index = get_metal_resource_index(var, SPIRType::Image, i); resources_in_set[desc_set].push_back( - { &var, descriptor_alias, to_name(var_id), SPIRType::Image, image_resource_index, i }); + { &var, to_name(var_id), SPIRType::Image, image_resource_index, i, 0 }); } if (type.image.dim != DimBuffer && !constexpr_sampler) { uint32_t sampler_resource_index = get_metal_resource_index(var, SPIRType::Sampler); resources_in_set[desc_set].push_back( - { &var, descriptor_alias, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index, 0 }); + { &var, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index, 0, 0 }); } } else if (inline_uniform_blocks.count(SetBindingPair{ desc_set, binding })) @@ -17951,19 +18228,17 @@ void CompilerMSL::analyze_argument_buffers() // Inline uniform blocks are always emitted at the end. add_resource_name(var_id); - uint32_t resource_index = ~0u; - if (!descriptor_alias) - resource_index = get_metal_resource_index(var, type.basetype); + uint32_t resource_index = get_metal_resource_index(var, type.basetype); resources_in_set[desc_set].push_back( - { &var, descriptor_alias, to_name(var_id), type.basetype, resource_index, 0 }); + { &var, to_name(var_id), type.basetype, resource_index, 0, 0 }); // Emulate texture2D atomic operations if (atomic_image_vars_emulated.count(var.self)) { uint32_t buffer_resource_index = get_metal_resource_index(var, SPIRType::AtomicCounter, 0); resources_in_set[desc_set].push_back( - { &var, descriptor_alias, to_name(var_id) + "_atomic", SPIRType::Struct, buffer_resource_index, 0 }); + { &var, to_name(var_id) + "_atomic", SPIRType::Struct, buffer_resource_index, 0, 0 }); } } @@ -18011,7 +18286,7 @@ void CompilerMSL::analyze_argument_buffers() set_decoration(var_id, DecorationDescriptorSet, desc_set); set_decoration(var_id, DecorationBinding, kSwizzleBufferBinding); resources_in_set[desc_set].push_back( - { &var, nullptr, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); + { &var, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0, 0 }); } if (set_needs_buffer_sizes[desc_set]) @@ -18022,7 +18297,7 @@ void CompilerMSL::analyze_argument_buffers() set_decoration(var_id, DecorationDescriptorSet, desc_set); set_decoration(var_id, DecorationBinding, kBufferSizeBufferBinding); resources_in_set[desc_set].push_back( - { &var, nullptr, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); + { &var, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0, 0 }); } } } @@ -18034,7 +18309,7 @@ void CompilerMSL::analyze_argument_buffers() uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet); add_resource_name(var_id); resources_in_set[desc_set].push_back( - { &var, nullptr, to_name(var_id), SPIRType::Struct, get_metal_resource_index(var, SPIRType::Struct), 0 }); + { &var, to_name(var_id), SPIRType::Struct, get_metal_resource_index(var, SPIRType::Struct), 0, 0 }); } for (uint32_t desc_set = 0; desc_set < kMaxArgumentBuffers; desc_set++) @@ -18083,6 +18358,22 @@ void CompilerMSL::analyze_argument_buffers() return tie(lhs.index, lhs.basetype) < tie(rhs.index, rhs.basetype); }); + for (size_t i = 0; i < resources.size() - 1; i++) + { + auto &r1 = resources[i]; + auto &r2 = resources[i + 1]; + + if (r1.index == r2.index) + { + if (r1.overlapping_var_id) + r2.overlapping_var_id = r1.overlapping_var_id; + else + r2.overlapping_var_id = r1.var->self; + + set_extended_decoration(r2.var->self, SPIRVCrossDecorationOverlappingBinding, r2.overlapping_var_id); + } + } + uint32_t member_index = 0; uint32_t next_arg_buff_index = 0; for (auto &resource : resources) @@ -18095,52 +18386,52 @@ void CompilerMSL::analyze_argument_buffers() // If needed, synthesize and add padding members. // member_index and next_arg_buff_index are incremented when padding members are added. - if (msl_options.pad_argument_buffer_resources) + if (msl_options.pad_argument_buffer_resources && resource.overlapping_var_id == 0) { - auto &rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); - if (!resource.descriptor_alias) + auto rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); + while (resource.index > next_arg_buff_index) { - while (resource.index > next_arg_buff_index) + switch (rez_bind.basetype) { - switch (rez_bind.basetype) - { - case SPIRType::Void: - case SPIRType::Boolean: - case SPIRType::SByte: - case SPIRType::UByte: - case SPIRType::Short: - case SPIRType::UShort: - case SPIRType::Int: - case SPIRType::UInt: - case SPIRType::Int64: - case SPIRType::UInt64: - case SPIRType::AtomicCounter: - case SPIRType::Half: - case SPIRType::Float: - case SPIRType::Double: - add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Image: - add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Sampler: + case SPIRType::Void: + case SPIRType::Boolean: + case SPIRType::SByte: + case SPIRType::UByte: + case SPIRType::Short: + case SPIRType::UShort: + case SPIRType::Int: + case SPIRType::UInt: + case SPIRType::Int64: + case SPIRType::UInt64: + case SPIRType::AtomicCounter: + case SPIRType::Half: + case SPIRType::Float: + case SPIRType::Double: + add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::Image: + add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::Sampler: + add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::SampledImage: + if (next_arg_buff_index == rez_bind.msl_sampler) add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::SampledImage: - if (next_arg_buff_index == rez_bind.msl_sampler) - add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - else - add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - default: - break; - } + else + add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + default: + break; } + + // After padding, retrieve the resource again. It will either be more padding, or the actual resource. + rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); } // Adjust the number of slots consumed by current member itself. // Use the count value from the app, instead of the shader, in case the - // shader is only accesing part, or even one element, of the array. + // shader is only accessing part, or even one element, of the array. next_arg_buff_index += rez_bind.count; } @@ -18182,23 +18473,29 @@ void CompilerMSL::analyze_argument_buffers() { // Drop pointer information when we emit the resources into a struct. buffer_type.member_types.push_back(get_variable_data_type_id(var)); - if (resource.plane == 0) + if (has_extended_decoration(var.self, SPIRVCrossDecorationOverlappingBinding)) + { + if (!msl_options.supports_msl_version(3, 0)) + SPIRV_CROSS_THROW("Full mutable aliasing of argument buffer descriptors only works on Metal 3+."); + + auto &entry_func = get(ir.default_entry_point); + entry_func.fixup_hooks_in.push_back([this, resource]() { + emit_argument_buffer_aliased_descriptor(*resource.var, this->get(resource.overlapping_var_id)); + }); + } + else if (resource.plane == 0) + { set_qualified_name(var.self, join(to_name(buffer_variable_id), ".", mbr_name)); + } } else if (buffers_requiring_dynamic_offset.count(pair)) { - if (resource.descriptor_alias) - SPIRV_CROSS_THROW("Descriptor aliasing is currently not supported with dynamic offsets."); - // Don't set the qualified name here; we'll define a variable holding the corrected buffer address later. buffer_type.member_types.push_back(var.basetype); buffers_requiring_dynamic_offset[pair].second = var.self; } else if (inline_uniform_blocks.count(pair)) { - if (resource.descriptor_alias) - SPIRV_CROSS_THROW("Descriptor aliasing is currently not supported with inline UBOs."); - // Put the buffer block itself into the argument buffer. buffer_type.member_types.push_back(get_variable_data_type_id(var)); set_qualified_name(var.self, join(to_name(buffer_variable_id), ".", mbr_name)); @@ -18231,11 +18528,22 @@ void CompilerMSL::analyze_argument_buffers() } else { - if (!resource.descriptor_alias || resource.descriptor_alias == resource.var) - buffer_type.member_types.push_back(var.basetype); + buffer_type.member_types.push_back(var.basetype); + if (has_extended_decoration(var.self, SPIRVCrossDecorationOverlappingBinding)) + { + // Casting raw pointers is fine since their ABI is fixed, but anything opaque is deeply questionable on Metal 2. + if (get(resource.overlapping_var_id).storage == StorageClassUniformConstant && + !msl_options.supports_msl_version(3, 0)) + { + SPIRV_CROSS_THROW("Full mutable aliasing of argument buffer descriptors only works on Metal 3+."); + } + + auto &entry_func = get(ir.default_entry_point); - if (resource.descriptor_alias && resource.descriptor_alias != resource.var) - buffer_aliases_argument.push_back({ var.self, resource.descriptor_alias->self }); + entry_func.fixup_hooks_in.push_back([this, resource]() { + emit_argument_buffer_aliased_descriptor(*resource.var, this->get(resource.overlapping_var_id)); + }); + } else if (type.array.empty()) set_qualified_name(var.self, join("(*", to_name(buffer_variable_id), ".", mbr_name, ")")); else @@ -18247,6 +18555,8 @@ void CompilerMSL::analyze_argument_buffers() resource.index); set_extended_member_decoration(buffer_type.self, member_index, SPIRVCrossDecorationInterfaceOrigID, var.self); + if (has_extended_decoration(var.self, SPIRVCrossDecorationOverlappingBinding)) + set_extended_member_decoration(buffer_type.self, member_index, SPIRVCrossDecorationOverlappingBinding); member_index++; } } @@ -18256,7 +18566,7 @@ void CompilerMSL::analyze_argument_buffers() // that matches the resource index of the argument buffer index. // This is a two-step lookup, first lookup the resource binding number from the argument buffer index, // then lookup the resource binding using the binding number. -MSLResourceBinding &CompilerMSL::get_argument_buffer_resource(uint32_t desc_set, uint32_t arg_idx) +const MSLResourceBinding &CompilerMSL::get_argument_buffer_resource(uint32_t desc_set, uint32_t arg_idx) const { auto stage = get_entry_point().model; StageSetBinding arg_idx_tuple = { stage, desc_set, arg_idx }; diff --git a/libs/bgfx/3rdparty/spirv-cross/spirv_msl.hpp b/libs/bgfx/3rdparty/spirv-cross/spirv_msl.hpp index ed91809..9a17158 100644 --- a/libs/bgfx/3rdparty/spirv-cross/spirv_msl.hpp +++ b/libs/bgfx/3rdparty/spirv-cross/spirv_msl.hpp @@ -287,9 +287,6 @@ static const uint32_t kArgumentBufferBinding = ~(3u); static const uint32_t kMaxArgumentBuffers = 8; -// The arbitrary maximum for the nesting of array of array copies. -static const uint32_t kArrayCopyMultidimMax = 6; - // Decompiles SPIR-V to Metal Shading Language class CompilerMSL : public CompilerGLSL { @@ -519,6 +516,26 @@ class CompilerMSL : public CompilerGLSL // transformed. bool agx_manual_cube_grad_fixup = false; + // Metal will discard fragments with side effects under certain circumstances prematurely. + // Example: CTS test dEQP-VK.fragment_operations.early_fragment.discard_no_early_fragment_tests_depth + // Test will render a full screen quad with varying depth [0,1] for each fragment. + // Each fragment will do an operation with side effects, modify the depth value and + // discard the fragment. The test expects the fragment to be run due to: + // https://registry.khronos.org/vulkan/specs/1.0-extensions/html/vkspec.html#fragops-shader-depthreplacement + // which states that the fragment shader must be run due to replacing the depth in shader. + // However, Metal may prematurely discards fragments without executing them + // (I believe this to be due to a greedy optimization on their end) making the test fail. + // This option enforces fragment execution for such cases where the fragment has operations + // with side effects. Provided as an option hoping Metal will fix this issue in the future. + bool force_fragment_with_side_effects_execution = false; + + // If set, adds a depth pass through statement to circumvent the following issue: + // When the same depth/stencil is used as input and depth/stencil attachment, we need to + // force Metal to perform the depth/stencil write after fragment execution. Otherwise, + // Metal will write to the depth attachment before fragment execution. This happens + // if the fragment does not modify the depth value. + bool input_attachment_is_ds_attachment = false; + bool is_ios() const { return platform == iOS; @@ -752,15 +769,8 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplFindSMsb, SPVFuncImplFindUMsb, SPVFuncImplSSign, - SPVFuncImplArrayCopyMultidimBase, - // Unfortunately, we cannot use recursive templates in the MSL compiler properly, - // so stamp out variants up to some arbitrary maximum. - SPVFuncImplArrayCopy = SPVFuncImplArrayCopyMultidimBase + 1, - SPVFuncImplArrayOfArrayCopy2Dim = SPVFuncImplArrayCopyMultidimBase + 2, - SPVFuncImplArrayOfArrayCopy3Dim = SPVFuncImplArrayCopyMultidimBase + 3, - SPVFuncImplArrayOfArrayCopy4Dim = SPVFuncImplArrayCopyMultidimBase + 4, - SPVFuncImplArrayOfArrayCopy5Dim = SPVFuncImplArrayCopyMultidimBase + 5, - SPVFuncImplArrayOfArrayCopy6Dim = SPVFuncImplArrayCopyMultidimBase + 6, + SPVFuncImplArrayCopy, + SPVFuncImplArrayCopyMultidim, SPVFuncImplTexelBufferCoords, SPVFuncImplImage2DAtomicCoords, // Emulate texture2D atomic operations SPVFuncImplGradientCube, @@ -782,6 +792,8 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplTextureSwizzle, SPVFuncImplGatherSwizzle, SPVFuncImplGatherCompareSwizzle, + SPVFuncImplGatherConstOffsets, + SPVFuncImplGatherCompareConstOffsets, SPVFuncImplSubgroupBroadcast, SPVFuncImplSubgroupBroadcastFirst, SPVFuncImplSubgroupBallot, @@ -824,7 +836,9 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplVariableSizedDescriptor, SPVFuncImplVariableDescriptorArray, SPVFuncImplPaddedStd140, - SPVFuncImplReduceAdd + SPVFuncImplReduceAdd, + SPVFuncImplImageFence, + SPVFuncImplTextureCast }; // If the underlying resource has been used for comparison then duplicate loads of that resource must be too @@ -855,7 +869,7 @@ class CompilerMSL : public CompilerGLSL void emit_block_hints(const SPIRBlock &block) override; // 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 type_to_array_glsl(const SPIRType &type, uint32_t variable_id) override; std::string constant_op_expression(const SPIRConstantOp &cop) override; bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override; @@ -959,7 +973,8 @@ class CompilerMSL : public CompilerGLSL uint32_t mbr_idx, InterfaceBlockMeta &meta, const std::string &mbr_name_qual, const std::string &var_chain_qual, - uint32_t &location, uint32_t &var_mbr_idx); + uint32_t &location, uint32_t &var_mbr_idx, + const Bitset &interpolation_qual); void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var); void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var); @@ -1086,6 +1101,7 @@ class CompilerMSL : public CompilerGLSL uint32_t builtin_stage_input_size_id = 0; uint32_t builtin_local_invocation_index_id = 0; uint32_t builtin_workgroup_size_id = 0; + uint32_t builtin_frag_depth_id = 0; uint32_t swizzle_buffer_id = 0; uint32_t buffer_size_buffer_id = 0; uint32_t view_mask_buffer_id = 0; @@ -1182,6 +1198,7 @@ class CompilerMSL : public CompilerGLSL bool needs_subgroup_size = false; bool needs_sample_id = false; bool needs_helper_invocation = false; + bool writes_to_depth = false; std::string qual_pos_var_name; std::string stage_in_var_name = "in"; std::string stage_out_var_name = "out"; @@ -1225,9 +1242,12 @@ class CompilerMSL : public CompilerGLSL uint32_t argument_buffer_discrete_mask = 0; uint32_t argument_buffer_device_storage_mask = 0; + void emit_argument_buffer_aliased_descriptor(const SPIRVariable &aliased_var, + const SPIRVariable &base_var); + void analyze_argument_buffers(); bool descriptor_set_is_argument_buffer(uint32_t desc_set) const; - MSLResourceBinding &get_argument_buffer_resource(uint32_t desc_set, uint32_t arg_idx); + const MSLResourceBinding &get_argument_buffer_resource(uint32_t desc_set, uint32_t arg_idx) const; void add_argument_buffer_padding_buffer_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); void add_argument_buffer_padding_image_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); void add_argument_buffer_padding_sampler_type(SPIRType &struct_type, uint32_t &mbr_idx, uint32_t &arg_buff_index, MSLResourceBinding &rez_bind); @@ -1239,14 +1259,13 @@ class CompilerMSL : public CompilerGLSL uint32_t build_msl_interpolant_type(uint32_t type_id, bool is_noperspective); bool suppress_missing_prototypes = false; + bool suppress_incompatible_pointer_types_discard_qualifiers = false; void add_spv_func_and_recompile(SPVFuncImpl spv_func); void activate_argument_buffer_resources(); bool type_is_msl_framebuffer_fetch(const SPIRType &type) const; - bool type_is_pointer(const SPIRType &type) const; - bool type_is_pointer_to_pointer(const SPIRType &type) const; bool is_supported_argument_buffer_type(const SPIRType &type) const; bool variable_storage_requires_stage_io(spv::StorageClass storage) const; diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml b/libs/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml index 4a2de83..f9b23ac 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/spir-v.xml @@ -92,7 +92,9 @@ - + + + @@ -155,7 +157,7 @@ sure to fill in the vendor attribute, and preferably add a contact person/address in a comment attribute. --> - + @@ -188,7 +190,7 @@ sure to fill in the vendor attribute, and preferably add a contact person/address in a comment attribute. --> - + @@ -208,8 +210,8 @@ - - + + @@ -269,8 +271,8 @@ - - + + diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVkspReflection.h b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVkspReflection.h index 0ef478a..331a3d9 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVkspReflection.h +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/NonSemanticVkspReflection.h @@ -33,7 +33,7 @@ extern "C" { #endif enum { - NonSemanticVkspReflectionRevision = 1, + NonSemanticVkspReflectionRevision = 2, NonSemanticVkspReflectionRevision_BitWidthPadding = 0x7fffffff }; diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json index bee1bea..379457b 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/extinst.nonsemantic.vkspreflection.grammar.json @@ -1,5 +1,5 @@ { - "revision" : 1, + "revision" : 2, "instructions" : [ { "opname" : "Configuration", @@ -12,7 +12,8 @@ {"kind" : "LiteralString", "name" : "EntryPoint" }, {"kind" : "LiteralInteger", "name" : "groupCountX" }, {"kind" : "LiteralInteger", "name" : "groupCountY" }, - {"kind" : "LiteralInteger", "name" : "groupCountZ" } + {"kind" : "LiteralInteger", "name" : "groupCountZ" }, + {"kind" : "LiteralInteger", "name" : "dispatchId" } ] }, { diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json index 03f3595..980b5dc 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.core.grammar.json @@ -4539,6 +4539,20 @@ "extensions" : [ "SPV_KHR_shader_ballot" ], "version" : "None" }, + { + "opname" : "OpExtInstWithForwardRefsKHR", + "class" : "Extension", + "opcode" : 4433, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Set'" }, + { "kind" : "LiteralExtInstInteger", "name" : "'Instruction'" }, + { "kind" : "IdRef", "quantifier" : "*", "name" : "'Operand 1', +\n'Operand 2', +\n..." } + ], + "extensions" : [ "SPV_KHR_relaxed_extended_instruction" ], + "version": "None" + }, { "opname" : "OpTraceRayKHR", "class" : "Reserved", @@ -4854,6 +4868,42 @@ "capabilities" : [ "CooperativeMatrixKHR" ], "version" : "None" }, + { + "opname" : "OpConstantCompositeReplicateEXT", + "class" : "Constant-Creation", + "opcode" : 4461, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "version" : "None" + }, + { + "opname" : "OpSpecConstantCompositeReplicateEXT", + "class" : "Constant-Creation", + "opcode" : 4462, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "version" : "None" + }, + { + "opname" : "OpCompositeConstructReplicateEXT", + "class" : "Composite", + "opcode" : 4463, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Value'" } + ], + "capabilities" : [ "ReplicatedCompositesEXT" ], + "version" : "None" + }, { "opname" : "OpTypeRayQueryKHR", "class" : "Type-Declaration", @@ -5888,7 +5938,7 @@ "version" : "None" }, { - "opname" : "OpReportIntersectionNV", + "opname" : "OpReportIntersectionKHR", "class" : "Reserved", "opcode" : 5334, "operands" : [ @@ -5902,7 +5952,7 @@ "version" : "None" }, { - "opname" : "OpReportIntersectionKHR", + "opname" : "OpReportIntersectionNV", "class" : "Reserved", "opcode" : 5334, "operands" : [ @@ -6019,7 +6069,7 @@ "version" : "None" }, { - "opname" : "OpTypeAccelerationStructureNV", + "opname" : "OpTypeAccelerationStructureKHR", "class" : "Type-Declaration", "opcode" : 5341, "operands" : [ @@ -6030,7 +6080,7 @@ "version" : "None" }, { - "opname" : "OpTypeAccelerationStructureKHR", + "opname" : "OpTypeAccelerationStructureNV", "class" : "Type-Declaration", "opcode" : 5341, "operands" : [ @@ -6251,6 +6301,24 @@ "capabilities" : [ "BindlessTextureNV" ], "version" : "None" }, + { + "opname" : "OpRawAccessChainNV", + "class" : "Memory", + "opcode" : 5398, + "operands" : [ + { "kind" : "IdResultType" }, + { "kind" : "IdResult" }, + { "kind" : "IdRef", "name" : "'Base'" }, + { "kind" : "IdRef", "name" : "'Byte stride'" }, + { "kind" : "IdRef", "name" : "'Element index'" }, + { "kind" : "IdRef", "name" : "'Byte offset'" }, + { "kind" : "RawAccessChainOperands", "quantifier" : "?" } + ], + "capabilities" : [ + "RawAccessChainsNV" + ], + "version" : "None" + }, { "opname" : "OpSubgroupShuffleINTEL", "class" : "Group", @@ -10667,6 +10735,28 @@ } ] }, + { + "category" : "BitEnum", + "kind" : "RawAccessChainOperands", + "enumerants" : [ + { + "enumerant" : "None", + "value" : "0x0000" + }, + { + "enumerant" : "RobustnessPerComponentNV", + "value" : "0x0001", + "capabilities" : [ "RawAccessChainsNV" ], + "version" : "None" + }, + { + "enumerant" : "RobustnessPerElementNV", + "value" : "0x0002", + "capabilities" : [ "RawAccessChainsNV" ], + "version" : "None" + } + ] + }, { "category" : "ValueEnum", "kind" : "SourceLanguage", @@ -10797,73 +10887,73 @@ "version" : "None" }, { - "enumerant" : "RayGenerationNV", + "enumerant" : "RayGenerationKHR", "value" : 5313, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "RayGenerationKHR", + "enumerant" : "RayGenerationNV", "value" : 5313, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IntersectionNV", + "enumerant" : "IntersectionKHR", "value" : 5314, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IntersectionKHR", + "enumerant" : "IntersectionNV", "value" : 5314, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "AnyHitNV", + "enumerant" : "AnyHitKHR", "value" : 5315, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "AnyHitKHR", + "enumerant" : "AnyHitNV", "value" : 5315, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "ClosestHitNV", + "enumerant" : "ClosestHitKHR", "value" : 5316, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "ClosestHitKHR", + "enumerant" : "ClosestHitNV", "value" : 5316, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "MissNV", + "enumerant" : "MissKHR", "value" : 5317, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "MissKHR", + "enumerant" : "MissNV", "value" : 5317, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "CallableNV", + "enumerant" : "CallableKHR", "value" : 5318, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "CallableKHR", + "enumerant" : "CallableNV", "value" : 5318, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" @@ -11421,21 +11511,21 @@ "version" : "None" }, { - "enumerant" : "OutputLinesNV", + "enumerant" : "OutputLinesEXT", "value" : 5269, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], "version" : "None" }, { - "enumerant" : "OutputLinesEXT", + "enumerant" : "OutputLinesNV", "value" : 5269, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], "version" : "None" }, { - "enumerant" : "OutputPrimitivesNV", + "enumerant" : "OutputPrimitivesEXT", "value" : 5270, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "parameters" : [ @@ -11445,7 +11535,7 @@ "version" : "None" }, { - "enumerant" : "OutputPrimitivesEXT", + "enumerant" : "OutputPrimitivesNV", "value" : 5270, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "parameters" : [ @@ -11469,14 +11559,14 @@ "version" : "None" }, { - "enumerant" : "OutputTrianglesNV", + "enumerant" : "OutputTrianglesEXT", "value" : 5298, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], "version" : "None" }, { - "enumerant" : "OutputTrianglesEXT", + "enumerant" : "OutputTrianglesNV", "value" : 5298, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], @@ -11660,6 +11750,33 @@ ], "capabilities" : [ "VectorComputeINTEL" ], "version" : "None" + }, + { + "enumerant" : "MaximumRegistersINTEL", + "value" : 6461, + "parameters" : [ + { "kind" : "LiteralInteger", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "MaximumRegistersIdINTEL", + "value" : 6462, + "parameters" : [ + { "kind" : "IdRef", "name" : "'Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + }, + { + "enumerant" : "NamedMaximumRegistersINTEL", + "value" : 6463, + "parameters" : [ + { "kind" : "NamedMaximumNumberOfRegisters", "name" : "'Named Maximum Number of Registers'" } + ], + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" } ] }, @@ -11762,84 +11879,84 @@ "version" : "None" }, { - "enumerant" : "CallableDataNV", + "enumerant" : "CallableDataKHR", "value" : 5328, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "CallableDataKHR", + "enumerant" : "CallableDataNV", "value" : 5328, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IncomingCallableDataNV", + "enumerant" : "IncomingCallableDataKHR", "value" : 5329, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IncomingCallableDataKHR", + "enumerant" : "IncomingCallableDataNV", "value" : 5329, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "RayPayloadNV", + "enumerant" : "RayPayloadKHR", "value" : 5338, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "RayPayloadKHR", + "enumerant" : "RayPayloadNV", "value" : 5338, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "HitAttributeNV", + "enumerant" : "HitAttributeKHR", "value" : 5339, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "HitAttributeKHR", + "enumerant" : "HitAttributeNV", "value" : 5339, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IncomingRayPayloadNV", + "enumerant" : "IncomingRayPayloadKHR", "value" : 5342, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "IncomingRayPayloadKHR", + "enumerant" : "IncomingRayPayloadNV", "value" : 5342, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "ShaderRecordBufferNV", + "enumerant" : "ShaderRecordBufferKHR", "value" : 5343, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "version" : "None" }, { - "enumerant" : "ShaderRecordBufferKHR", + "enumerant" : "ShaderRecordBufferNV", "value" : 5343, "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], @@ -13196,14 +13313,14 @@ ] }, { - "enumerant" : "PerPrimitiveNV", + "enumerant" : "PerPrimitiveEXT", "value" : 5271, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], "version" : "None" }, { - "enumerant" : "PerPrimitiveEXT", + "enumerant" : "PerPrimitiveNV", "value" : 5271, "capabilities" : [ "MeshShadingNV", "MeshShadingEXT" ], "extensions" : [ "SPV_NV_mesh_shader", "SPV_EXT_mesh_shader" ], @@ -14503,154 +14620,154 @@ "version" : "None" }, { - "enumerant" : "LaunchIdNV", + "enumerant" : "LaunchIdKHR", "value" : 5319, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "LaunchIdKHR", + "enumerant" : "LaunchIdNV", "value" : 5319, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "LaunchSizeNV", + "enumerant" : "LaunchSizeKHR", "value" : 5320, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "LaunchSizeKHR", + "enumerant" : "LaunchSizeNV", "value" : 5320, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldRayOriginNV", + "enumerant" : "WorldRayOriginKHR", "value" : 5321, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldRayOriginKHR", + "enumerant" : "WorldRayOriginNV", "value" : 5321, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldRayDirectionNV", + "enumerant" : "WorldRayDirectionKHR", "value" : 5322, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldRayDirectionKHR", + "enumerant" : "WorldRayDirectionNV", "value" : 5322, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectRayOriginNV", + "enumerant" : "ObjectRayOriginKHR", "value" : 5323, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectRayOriginKHR", + "enumerant" : "ObjectRayOriginNV", "value" : 5323, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectRayDirectionNV", + "enumerant" : "ObjectRayDirectionKHR", "value" : 5324, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectRayDirectionKHR", + "enumerant" : "ObjectRayDirectionNV", "value" : 5324, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "RayTminNV", + "enumerant" : "RayTminKHR", "value" : 5325, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "RayTminKHR", + "enumerant" : "RayTminNV", "value" : 5325, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "RayTmaxNV", + "enumerant" : "RayTmaxKHR", "value" : 5326, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "RayTmaxKHR", + "enumerant" : "RayTmaxNV", "value" : 5326, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "InstanceCustomIndexNV", + "enumerant" : "InstanceCustomIndexKHR", "value" : 5327, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "InstanceCustomIndexKHR", + "enumerant" : "InstanceCustomIndexNV", "value" : 5327, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectToWorldNV", + "enumerant" : "ObjectToWorldKHR", "value" : 5330, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "ObjectToWorldKHR", + "enumerant" : "ObjectToWorldNV", "value" : 5330, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldToObjectNV", + "enumerant" : "WorldToObjectKHR", "value" : 5331, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "WorldToObjectKHR", + "enumerant" : "WorldToObjectNV", "value" : 5331, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], @@ -14664,14 +14781,14 @@ "version" : "None" }, { - "enumerant" : "HitKindNV", + "enumerant" : "HitKindKHR", "value" : 5333, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "HitKindKHR", + "enumerant" : "HitKindNV", "value" : 5333, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], @@ -14703,14 +14820,14 @@ "version" : "None" }, { - "enumerant" : "IncomingRayFlagsNV", + "enumerant" : "IncomingRayFlagsKHR", "value" : 5351, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], "version" : "None" }, { - "enumerant" : "IncomingRayFlagsKHR", + "enumerant" : "IncomingRayFlagsNV", "value" : 5351, "capabilities" : [ "RayTracingNV" , "RayTracingKHR" ], "extensions" : [ "SPV_NV_ray_tracing" , "SPV_KHR_ray_tracing" ], @@ -15329,6 +15446,12 @@ "extensions" : [ "SPV_EXT_shader_tile_image" ], "version" : "None" }, + { + "enumerant" : "CooperativeMatrixLayoutsARM", + "value" : 4201, + "extensions" : [ "SPV_ARM_cooperative_matrix_layouts" ], + "version" : "None" + }, { "enumerant" : "FragmentShadingRateKHR", "value" : 4422, @@ -16056,6 +16179,12 @@ "extensions" : [ "SPV_NV_displacement_micromap" ], "version" : "None" }, + { + "enumerant" : "RawAccessChainsNV", + "value" : 5414, + "extensions" : [ "SPV_NV_raw_access_chains" ], + "version" : "None" + }, { "enumerant" : "SubgroupShuffleINTEL", "value" : 5568, @@ -16369,6 +16498,12 @@ "extensions" : [ "SPV_KHR_cooperative_matrix" ], "version" : "None" }, + { + "enumerant" : "ReplicatedCompositesEXT", + "value" : 6024, + "extensions" : [ "SPV_EXT_replicated_composites" ], + "version" : "None" + }, { "enumerant" : "BitInstructions", "value" : 6025, @@ -16497,6 +16632,12 @@ "value" : 6441, "extensions" : [ "SPV_INTEL_cache_controls" ], "version" : "None" + }, + { + "enumerant" : "RegisterLimitsINTEL", + "value" : 6460, + "extensions" : [ "SPV_INTEL_maximum_registers" ], + "version" : "None" } ] }, @@ -16626,6 +16767,16 @@ "enumerant" : "ColumnMajorKHR", "value" : 1, "version" : "None" + }, + { + "enumerant" : "RowBlockedInterleavedARM", + "value" : 4202, + "version" : "None" + }, + { + "enumerant" : "ColumnBlockedInterleavedARM", + "value" : 4203, + "version" : "None" } ] }, @@ -16734,6 +16885,18 @@ } ] }, + { + "category" : "ValueEnum", + "kind" : "NamedMaximumNumberOfRegisters", + "enumerants" : [ + { + "enumerant" : "AutoINTEL", + "value" : 0, + "capabilities" : [ "RegisterLimitsINTEL" ], + "version" : "None" + } + ] + }, { "category" : "Id", "kind" : "IdResultType", diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h index 96928b1..42790e0 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.h @@ -219,6 +219,9 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeStreamingInterfaceINTEL = 6154, SpvExecutionModeRegisterMapInterfaceINTEL = 6160, SpvExecutionModeNamedBarrierCountINTEL = 6417, + SpvExecutionModeMaximumRegistersINTEL = 6461, + SpvExecutionModeMaximumRegistersIdINTEL = 6462, + SpvExecutionModeNamedMaximumRegistersINTEL = 6463, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -1046,6 +1049,7 @@ typedef enum SpvCapability_ { SpvCapabilityTileImageColorReadAccessEXT = 4166, SpvCapabilityTileImageDepthReadAccessEXT = 4167, SpvCapabilityTileImageStencilReadAccessEXT = 4168, + SpvCapabilityCooperativeMatrixLayoutsARM = 4201, SpvCapabilityFragmentShadingRateKHR = 4422, SpvCapabilitySubgroupBallotKHR = 4423, SpvCapabilityDrawParameters = 4427, @@ -1156,6 +1160,7 @@ typedef enum SpvCapability_ { SpvCapabilityRayQueryPositionFetchKHR = 5391, SpvCapabilityAtomicFloat16VectorNV = 5404, SpvCapabilityRayTracingDisplacementMicromapNV = 5409, + SpvCapabilityRawAccessChainsNV = 5414, SpvCapabilitySubgroupShuffleINTEL = 5568, SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, SpvCapabilitySubgroupImageBlockIOINTEL = 5570, @@ -1208,6 +1213,7 @@ typedef enum SpvCapability_ { SpvCapabilityDotProductKHR = 6019, SpvCapabilityRayCullMaskKHR = 6020, SpvCapabilityCooperativeMatrixKHR = 6022, + SpvCapabilityReplicatedCompositesEXT = 6024, SpvCapabilityBitInstructions = 6025, SpvCapabilityGroupNonUniformRotateKHR = 6026, SpvCapabilityFloatControls2 = 6029, @@ -1229,6 +1235,7 @@ typedef enum SpvCapability_ { SpvCapabilityGroupUniformArithmeticKHR = 6400, SpvCapabilityMaskedGatherScatterINTEL = 6427, SpvCapabilityCacheControlsINTEL = 6441, + SpvCapabilityRegisterLimitsINTEL = 6460, SpvCapabilityMax = 0x7fffffff, } SpvCapability; @@ -1356,6 +1363,8 @@ typedef enum SpvCooperativeMatrixOperandsMask_ { typedef enum SpvCooperativeMatrixLayout_ { SpvCooperativeMatrixLayoutRowMajorKHR = 0, SpvCooperativeMatrixLayoutColumnMajorKHR = 1, + SpvCooperativeMatrixLayoutRowBlockedInterleavedARM = 4202, + SpvCooperativeMatrixLayoutColumnBlockedInterleavedARM = 4203, SpvCooperativeMatrixLayoutMax = 0x7fffffff, } SpvCooperativeMatrixLayout; @@ -1397,6 +1406,23 @@ typedef enum SpvStoreCacheControl_ { SpvStoreCacheControlMax = 0x7fffffff, } SpvStoreCacheControl; +typedef enum SpvNamedMaximumNumberOfRegisters_ { + SpvNamedMaximumNumberOfRegistersAutoINTEL = 0, + SpvNamedMaximumNumberOfRegistersMax = 0x7fffffff, +} SpvNamedMaximumNumberOfRegisters; + +typedef enum SpvRawAccessChainOperandsShift_ { + SpvRawAccessChainOperandsRobustnessPerComponentNVShift = 0, + SpvRawAccessChainOperandsRobustnessPerElementNVShift = 1, + SpvRawAccessChainOperandsMax = 0x7fffffff, +} SpvRawAccessChainOperandsShift; + +typedef enum SpvRawAccessChainOperandsMask_ { + SpvRawAccessChainOperandsMaskNone = 0, + SpvRawAccessChainOperandsRobustnessPerComponentNVMask = 0x00000001, + SpvRawAccessChainOperandsRobustnessPerElementNVMask = 0x00000002, +} SpvRawAccessChainOperandsMask; + typedef enum SpvOp_ { SpvOpNop = 0, SpvOpUndef = 1, @@ -1753,6 +1779,7 @@ typedef enum SpvOp_ { SpvOpSubgroupAllEqualKHR = 4430, SpvOpGroupNonUniformRotateKHR = 4431, SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpExtInstWithForwardRefsKHR = 4433, SpvOpTraceRayKHR = 4445, SpvOpExecuteCallableKHR = 4446, SpvOpConvertUToAccelerationStructureKHR = 4447, @@ -1775,6 +1802,9 @@ typedef enum SpvOp_ { SpvOpCooperativeMatrixStoreKHR = 4458, SpvOpCooperativeMatrixMulAddKHR = 4459, SpvOpCooperativeMatrixLengthKHR = 4460, + SpvOpConstantCompositeReplicateEXT = 4461, + SpvOpSpecConstantCompositeReplicateEXT = 4462, + SpvOpCompositeConstructReplicateEXT = 4463, SpvOpTypeRayQueryKHR = 4472, SpvOpRayQueryInitializeKHR = 4473, SpvOpRayQueryTerminateKHR = 4474, @@ -1874,6 +1904,7 @@ typedef enum SpvOp_ { SpvOpConvertUToSampledImageNV = 5395, SpvOpConvertSampledImageToUNV = 5396, SpvOpSamplerImageAddressingModeNV = 5397, + SpvOpRawAccessChainNV = 5398, SpvOpSubgroupShuffleINTEL = 5571, SpvOpSubgroupShuffleDownINTEL = 5572, SpvOpSubgroupShuffleUpINTEL = 5573, @@ -2496,6 +2527,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break; case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; @@ -2512,6 +2544,9 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; case SpvOpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; case SpvOpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break; case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; @@ -2583,14 +2618,14 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; case SpvOpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; case SpvOpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; - case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case SpvOpReportIntersectionKHR: *hasResult = true; *hasResultType = true; break; 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 SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeAccelerationStructureKHR: *hasResult = true; *hasResultType = false; break; case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; @@ -2608,6 +2643,7 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case SpvOpRawAccessChainNV: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; @@ -2864,6 +2900,1787 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; } } +inline const char* SpvSourceLanguageToString(SpvSourceLanguage value) { + switch (value) { + case SpvSourceLanguageUnknown: return "Unknown"; + case SpvSourceLanguageESSL: return "ESSL"; + case SpvSourceLanguageGLSL: return "GLSL"; + case SpvSourceLanguageOpenCL_C: return "OpenCL_C"; + case SpvSourceLanguageOpenCL_CPP: return "OpenCL_CPP"; + case SpvSourceLanguageHLSL: return "HLSL"; + case SpvSourceLanguageCPP_for_OpenCL: return "CPP_for_OpenCL"; + case SpvSourceLanguageSYCL: return "SYCL"; + case SpvSourceLanguageHERO_C: return "HERO_C"; + case SpvSourceLanguageNZSL: return "NZSL"; + case SpvSourceLanguageWGSL: return "WGSL"; + case SpvSourceLanguageSlang: return "Slang"; + case SpvSourceLanguageZig: return "Zig"; + default: return "Unknown"; + } +} + +inline const char* SpvExecutionModelToString(SpvExecutionModel value) { + switch (value) { + case SpvExecutionModelVertex: return "Vertex"; + case SpvExecutionModelTessellationControl: return "TessellationControl"; + case SpvExecutionModelTessellationEvaluation: return "TessellationEvaluation"; + case SpvExecutionModelGeometry: return "Geometry"; + case SpvExecutionModelFragment: return "Fragment"; + case SpvExecutionModelGLCompute: return "GLCompute"; + case SpvExecutionModelKernel: return "Kernel"; + case SpvExecutionModelTaskNV: return "TaskNV"; + case SpvExecutionModelMeshNV: return "MeshNV"; + case SpvExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case SpvExecutionModelIntersectionKHR: return "IntersectionKHR"; + case SpvExecutionModelAnyHitKHR: return "AnyHitKHR"; + case SpvExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case SpvExecutionModelMissKHR: return "MissKHR"; + case SpvExecutionModelCallableKHR: return "CallableKHR"; + case SpvExecutionModelTaskEXT: return "TaskEXT"; + case SpvExecutionModelMeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* SpvAddressingModelToString(SpvAddressingModel value) { + switch (value) { + case SpvAddressingModelLogical: return "Logical"; + case SpvAddressingModelPhysical32: return "Physical32"; + case SpvAddressingModelPhysical64: return "Physical64"; + case SpvAddressingModelPhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* SpvMemoryModelToString(SpvMemoryModel value) { + switch (value) { + case SpvMemoryModelSimple: return "Simple"; + case SpvMemoryModelGLSL450: return "GLSL450"; + case SpvMemoryModelOpenCL: return "OpenCL"; + case SpvMemoryModelVulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* SpvExecutionModeToString(SpvExecutionMode value) { + switch (value) { + case SpvExecutionModeInvocations: return "Invocations"; + case SpvExecutionModeSpacingEqual: return "SpacingEqual"; + case SpvExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case SpvExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case SpvExecutionModeVertexOrderCw: return "VertexOrderCw"; + case SpvExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case SpvExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case SpvExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case SpvExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case SpvExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case SpvExecutionModePointMode: return "PointMode"; + case SpvExecutionModeXfb: return "Xfb"; + case SpvExecutionModeDepthReplacing: return "DepthReplacing"; + case SpvExecutionModeDepthGreater: return "DepthGreater"; + case SpvExecutionModeDepthLess: return "DepthLess"; + case SpvExecutionModeDepthUnchanged: return "DepthUnchanged"; + case SpvExecutionModeLocalSize: return "LocalSize"; + case SpvExecutionModeLocalSizeHint: return "LocalSizeHint"; + case SpvExecutionModeInputPoints: return "InputPoints"; + case SpvExecutionModeInputLines: return "InputLines"; + case SpvExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case SpvExecutionModeTriangles: return "Triangles"; + case SpvExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case SpvExecutionModeQuads: return "Quads"; + case SpvExecutionModeIsolines: return "Isolines"; + case SpvExecutionModeOutputVertices: return "OutputVertices"; + case SpvExecutionModeOutputPoints: return "OutputPoints"; + case SpvExecutionModeOutputLineStrip: return "OutputLineStrip"; + case SpvExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case SpvExecutionModeVecTypeHint: return "VecTypeHint"; + case SpvExecutionModeContractionOff: return "ContractionOff"; + case SpvExecutionModeInitializer: return "Initializer"; + case SpvExecutionModeFinalizer: return "Finalizer"; + case SpvExecutionModeSubgroupSize: return "SubgroupSize"; + case SpvExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case SpvExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case SpvExecutionModeLocalSizeId: return "LocalSizeId"; + case SpvExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + case SpvExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case SpvExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case SpvExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case SpvExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case SpvExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case SpvExecutionModeDenormPreserve: return "DenormPreserve"; + case SpvExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case SpvExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case SpvExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case SpvExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case SpvExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case SpvExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case SpvExecutionModeCoalescingAMDX: return "CoalescingAMDX"; + case SpvExecutionModeMaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case SpvExecutionModeStaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case SpvExecutionModeShaderIndexAMDX: return "ShaderIndexAMDX"; + case SpvExecutionModeMaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case SpvExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case SpvExecutionModeStencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case SpvExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case SpvExecutionModeStencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case SpvExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case SpvExecutionModeStencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case SpvExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR"; + case SpvExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case SpvExecutionModeOutputLinesEXT: return "OutputLinesEXT"; + case SpvExecutionModeOutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case SpvExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case SpvExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case SpvExecutionModeOutputTrianglesEXT: return "OutputTrianglesEXT"; + case SpvExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case SpvExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case SpvExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case SpvExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case SpvExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case SpvExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case SpvExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case SpvExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case SpvExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case SpvExecutionModeFloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case SpvExecutionModeFloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case SpvExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case SpvExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case SpvExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case SpvExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case SpvExecutionModeSchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case SpvExecutionModeMaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case SpvExecutionModeFPFastMathDefault: return "FPFastMathDefault"; + case SpvExecutionModeStreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case SpvExecutionModeRegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case SpvExecutionModeNamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case SpvExecutionModeMaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case SpvExecutionModeMaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case SpvExecutionModeNamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvStorageClassToString(SpvStorageClass value) { + switch (value) { + case SpvStorageClassUniformConstant: return "UniformConstant"; + case SpvStorageClassInput: return "Input"; + case SpvStorageClassUniform: return "Uniform"; + case SpvStorageClassOutput: return "Output"; + case SpvStorageClassWorkgroup: return "Workgroup"; + case SpvStorageClassCrossWorkgroup: return "CrossWorkgroup"; + case SpvStorageClassPrivate: return "Private"; + case SpvStorageClassFunction: return "Function"; + case SpvStorageClassGeneric: return "Generic"; + case SpvStorageClassPushConstant: return "PushConstant"; + case SpvStorageClassAtomicCounter: return "AtomicCounter"; + case SpvStorageClassImage: return "Image"; + case SpvStorageClassStorageBuffer: return "StorageBuffer"; + case SpvStorageClassTileImageEXT: return "TileImageEXT"; + case SpvStorageClassNodePayloadAMDX: return "NodePayloadAMDX"; + case SpvStorageClassNodeOutputPayloadAMDX: return "NodeOutputPayloadAMDX"; + case SpvStorageClassCallableDataKHR: return "CallableDataKHR"; + case SpvStorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case SpvStorageClassRayPayloadKHR: return "RayPayloadKHR"; + case SpvStorageClassHitAttributeKHR: return "HitAttributeKHR"; + case SpvStorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case SpvStorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case SpvStorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case SpvStorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case SpvStorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case SpvStorageClassCodeSectionINTEL: return "CodeSectionINTEL"; + case SpvStorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case SpvStorageClassHostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvDimToString(SpvDim value) { + switch (value) { + case SpvDim1D: return "1D"; + case SpvDim2D: return "2D"; + case SpvDim3D: return "3D"; + case SpvDimCube: return "Cube"; + case SpvDimRect: return "Rect"; + case SpvDimBuffer: return "Buffer"; + case SpvDimSubpassData: return "SubpassData"; + case SpvDimTileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SpvSamplerAddressingModeToString(SpvSamplerAddressingMode value) { + switch (value) { + case SpvSamplerAddressingModeNone: return "None"; + case SpvSamplerAddressingModeClampToEdge: return "ClampToEdge"; + case SpvSamplerAddressingModeClamp: return "Clamp"; + case SpvSamplerAddressingModeRepeat: return "Repeat"; + case SpvSamplerAddressingModeRepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SpvSamplerFilterModeToString(SpvSamplerFilterMode value) { + switch (value) { + case SpvSamplerFilterModeNearest: return "Nearest"; + case SpvSamplerFilterModeLinear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* SpvImageFormatToString(SpvImageFormat value) { + switch (value) { + case SpvImageFormatUnknown: return "Unknown"; + case SpvImageFormatRgba32f: return "Rgba32f"; + case SpvImageFormatRgba16f: return "Rgba16f"; + case SpvImageFormatR32f: return "R32f"; + case SpvImageFormatRgba8: return "Rgba8"; + case SpvImageFormatRgba8Snorm: return "Rgba8Snorm"; + case SpvImageFormatRg32f: return "Rg32f"; + case SpvImageFormatRg16f: return "Rg16f"; + case SpvImageFormatR11fG11fB10f: return "R11fG11fB10f"; + case SpvImageFormatR16f: return "R16f"; + case SpvImageFormatRgba16: return "Rgba16"; + case SpvImageFormatRgb10A2: return "Rgb10A2"; + case SpvImageFormatRg16: return "Rg16"; + case SpvImageFormatRg8: return "Rg8"; + case SpvImageFormatR16: return "R16"; + case SpvImageFormatR8: return "R8"; + case SpvImageFormatRgba16Snorm: return "Rgba16Snorm"; + case SpvImageFormatRg16Snorm: return "Rg16Snorm"; + case SpvImageFormatRg8Snorm: return "Rg8Snorm"; + case SpvImageFormatR16Snorm: return "R16Snorm"; + case SpvImageFormatR8Snorm: return "R8Snorm"; + case SpvImageFormatRgba32i: return "Rgba32i"; + case SpvImageFormatRgba16i: return "Rgba16i"; + case SpvImageFormatRgba8i: return "Rgba8i"; + case SpvImageFormatR32i: return "R32i"; + case SpvImageFormatRg32i: return "Rg32i"; + case SpvImageFormatRg16i: return "Rg16i"; + case SpvImageFormatRg8i: return "Rg8i"; + case SpvImageFormatR16i: return "R16i"; + case SpvImageFormatR8i: return "R8i"; + case SpvImageFormatRgba32ui: return "Rgba32ui"; + case SpvImageFormatRgba16ui: return "Rgba16ui"; + case SpvImageFormatRgba8ui: return "Rgba8ui"; + case SpvImageFormatR32ui: return "R32ui"; + case SpvImageFormatRgb10a2ui: return "Rgb10a2ui"; + case SpvImageFormatRg32ui: return "Rg32ui"; + case SpvImageFormatRg16ui: return "Rg16ui"; + case SpvImageFormatRg8ui: return "Rg8ui"; + case SpvImageFormatR16ui: return "R16ui"; + case SpvImageFormatR8ui: return "R8ui"; + case SpvImageFormatR64ui: return "R64ui"; + case SpvImageFormatR64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* SpvImageChannelOrderToString(SpvImageChannelOrder value) { + switch (value) { + case SpvImageChannelOrderR: return "R"; + case SpvImageChannelOrderA: return "A"; + case SpvImageChannelOrderRG: return "RG"; + case SpvImageChannelOrderRA: return "RA"; + case SpvImageChannelOrderRGB: return "RGB"; + case SpvImageChannelOrderRGBA: return "RGBA"; + case SpvImageChannelOrderBGRA: return "BGRA"; + case SpvImageChannelOrderARGB: return "ARGB"; + case SpvImageChannelOrderIntensity: return "Intensity"; + case SpvImageChannelOrderLuminance: return "Luminance"; + case SpvImageChannelOrderRx: return "Rx"; + case SpvImageChannelOrderRGx: return "RGx"; + case SpvImageChannelOrderRGBx: return "RGBx"; + case SpvImageChannelOrderDepth: return "Depth"; + case SpvImageChannelOrderDepthStencil: return "DepthStencil"; + case SpvImageChannelOrdersRGB: return "sRGB"; + case SpvImageChannelOrdersRGBx: return "sRGBx"; + case SpvImageChannelOrdersRGBA: return "sRGBA"; + case SpvImageChannelOrdersBGRA: return "sBGRA"; + case SpvImageChannelOrderABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* SpvImageChannelDataTypeToString(SpvImageChannelDataType value) { + switch (value) { + case SpvImageChannelDataTypeSnormInt8: return "SnormInt8"; + case SpvImageChannelDataTypeSnormInt16: return "SnormInt16"; + case SpvImageChannelDataTypeUnormInt8: return "UnormInt8"; + case SpvImageChannelDataTypeUnormInt16: return "UnormInt16"; + case SpvImageChannelDataTypeUnormShort565: return "UnormShort565"; + case SpvImageChannelDataTypeUnormShort555: return "UnormShort555"; + case SpvImageChannelDataTypeUnormInt101010: return "UnormInt101010"; + case SpvImageChannelDataTypeSignedInt8: return "SignedInt8"; + case SpvImageChannelDataTypeSignedInt16: return "SignedInt16"; + case SpvImageChannelDataTypeSignedInt32: return "SignedInt32"; + case SpvImageChannelDataTypeUnsignedInt8: return "UnsignedInt8"; + case SpvImageChannelDataTypeUnsignedInt16: return "UnsignedInt16"; + case SpvImageChannelDataTypeUnsignedInt32: return "UnsignedInt32"; + case SpvImageChannelDataTypeHalfFloat: return "HalfFloat"; + case SpvImageChannelDataTypeFloat: return "Float"; + case SpvImageChannelDataTypeUnormInt24: return "UnormInt24"; + case SpvImageChannelDataTypeUnormInt101010_2: return "UnormInt101010_2"; + case SpvImageChannelDataTypeUnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case SpvImageChannelDataTypeUnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + default: return "Unknown"; + } +} + +inline const char* SpvFPRoundingModeToString(SpvFPRoundingMode value) { + switch (value) { + case SpvFPRoundingModeRTE: return "RTE"; + case SpvFPRoundingModeRTZ: return "RTZ"; + case SpvFPRoundingModeRTP: return "RTP"; + case SpvFPRoundingModeRTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* SpvLinkageTypeToString(SpvLinkageType value) { + switch (value) { + case SpvLinkageTypeExport: return "Export"; + case SpvLinkageTypeImport: return "Import"; + case SpvLinkageTypeLinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* SpvAccessQualifierToString(SpvAccessQualifier value) { + switch (value) { + case SpvAccessQualifierReadOnly: return "ReadOnly"; + case SpvAccessQualifierWriteOnly: return "WriteOnly"; + case SpvAccessQualifierReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* SpvFunctionParameterAttributeToString(SpvFunctionParameterAttribute value) { + switch (value) { + case SpvFunctionParameterAttributeZext: return "Zext"; + case SpvFunctionParameterAttributeSext: return "Sext"; + case SpvFunctionParameterAttributeByVal: return "ByVal"; + case SpvFunctionParameterAttributeSret: return "Sret"; + case SpvFunctionParameterAttributeNoAlias: return "NoAlias"; + case SpvFunctionParameterAttributeNoCapture: return "NoCapture"; + case SpvFunctionParameterAttributeNoWrite: return "NoWrite"; + case SpvFunctionParameterAttributeNoReadWrite: return "NoReadWrite"; + case SpvFunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvDecorationToString(SpvDecoration value) { + switch (value) { + case SpvDecorationRelaxedPrecision: return "RelaxedPrecision"; + case SpvDecorationSpecId: return "SpecId"; + case SpvDecorationBlock: return "Block"; + case SpvDecorationBufferBlock: return "BufferBlock"; + case SpvDecorationRowMajor: return "RowMajor"; + case SpvDecorationColMajor: return "ColMajor"; + case SpvDecorationArrayStride: return "ArrayStride"; + case SpvDecorationMatrixStride: return "MatrixStride"; + case SpvDecorationGLSLShared: return "GLSLShared"; + case SpvDecorationGLSLPacked: return "GLSLPacked"; + case SpvDecorationCPacked: return "CPacked"; + case SpvDecorationBuiltIn: return "BuiltIn"; + case SpvDecorationNoPerspective: return "NoPerspective"; + case SpvDecorationFlat: return "Flat"; + case SpvDecorationPatch: return "Patch"; + case SpvDecorationCentroid: return "Centroid"; + case SpvDecorationSample: return "Sample"; + case SpvDecorationInvariant: return "Invariant"; + case SpvDecorationRestrict: return "Restrict"; + case SpvDecorationAliased: return "Aliased"; + case SpvDecorationVolatile: return "Volatile"; + case SpvDecorationConstant: return "Constant"; + case SpvDecorationCoherent: return "Coherent"; + case SpvDecorationNonWritable: return "NonWritable"; + case SpvDecorationNonReadable: return "NonReadable"; + case SpvDecorationUniform: return "Uniform"; + case SpvDecorationUniformId: return "UniformId"; + case SpvDecorationSaturatedConversion: return "SaturatedConversion"; + case SpvDecorationStream: return "Stream"; + case SpvDecorationLocation: return "Location"; + case SpvDecorationComponent: return "Component"; + case SpvDecorationIndex: return "Index"; + case SpvDecorationBinding: return "Binding"; + case SpvDecorationDescriptorSet: return "DescriptorSet"; + case SpvDecorationOffset: return "Offset"; + case SpvDecorationXfbBuffer: return "XfbBuffer"; + case SpvDecorationXfbStride: return "XfbStride"; + case SpvDecorationFuncParamAttr: return "FuncParamAttr"; + case SpvDecorationFPRoundingMode: return "FPRoundingMode"; + case SpvDecorationFPFastMathMode: return "FPFastMathMode"; + case SpvDecorationLinkageAttributes: return "LinkageAttributes"; + case SpvDecorationNoContraction: return "NoContraction"; + case SpvDecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case SpvDecorationAlignment: return "Alignment"; + case SpvDecorationMaxByteOffset: return "MaxByteOffset"; + case SpvDecorationAlignmentId: return "AlignmentId"; + case SpvDecorationMaxByteOffsetId: return "MaxByteOffsetId"; + case SpvDecorationNoSignedWrap: return "NoSignedWrap"; + case SpvDecorationNoUnsignedWrap: return "NoUnsignedWrap"; + case SpvDecorationWeightTextureQCOM: return "WeightTextureQCOM"; + case SpvDecorationBlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case SpvDecorationBlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case SpvDecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case SpvDecorationNodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case SpvDecorationNodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case SpvDecorationTrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case SpvDecorationPayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case SpvDecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case SpvDecorationPassthroughNV: return "PassthroughNV"; + case SpvDecorationViewportRelativeNV: return "ViewportRelativeNV"; + case SpvDecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case SpvDecorationPerPrimitiveEXT: return "PerPrimitiveEXT"; + case SpvDecorationPerViewNV: return "PerViewNV"; + case SpvDecorationPerTaskNV: return "PerTaskNV"; + case SpvDecorationPerVertexKHR: return "PerVertexKHR"; + case SpvDecorationNonUniform: return "NonUniform"; + case SpvDecorationRestrictPointer: return "RestrictPointer"; + case SpvDecorationAliasedPointer: return "AliasedPointer"; + case SpvDecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case SpvDecorationBindlessSamplerNV: return "BindlessSamplerNV"; + case SpvDecorationBindlessImageNV: return "BindlessImageNV"; + case SpvDecorationBoundSamplerNV: return "BoundSamplerNV"; + case SpvDecorationBoundImageNV: return "BoundImageNV"; + case SpvDecorationSIMTCallINTEL: return "SIMTCallINTEL"; + case SpvDecorationReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case SpvDecorationClobberINTEL: return "ClobberINTEL"; + case SpvDecorationSideEffectsINTEL: return "SideEffectsINTEL"; + case SpvDecorationVectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case SpvDecorationFuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case SpvDecorationVectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case SpvDecorationStackCallINTEL: return "StackCallINTEL"; + case SpvDecorationGlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case SpvDecorationCounterBuffer: return "CounterBuffer"; + case SpvDecorationHlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case SpvDecorationUserTypeGOOGLE: return "UserTypeGOOGLE"; + case SpvDecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case SpvDecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case SpvDecorationRegisterINTEL: return "RegisterINTEL"; + case SpvDecorationMemoryINTEL: return "MemoryINTEL"; + case SpvDecorationNumbanksINTEL: return "NumbanksINTEL"; + case SpvDecorationBankwidthINTEL: return "BankwidthINTEL"; + case SpvDecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case SpvDecorationSinglepumpINTEL: return "SinglepumpINTEL"; + case SpvDecorationDoublepumpINTEL: return "DoublepumpINTEL"; + case SpvDecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case SpvDecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case SpvDecorationMergeINTEL: return "MergeINTEL"; + case SpvDecorationBankBitsINTEL: return "BankBitsINTEL"; + case SpvDecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case SpvDecorationStridesizeINTEL: return "StridesizeINTEL"; + case SpvDecorationWordsizeINTEL: return "WordsizeINTEL"; + case SpvDecorationTrueDualPortINTEL: return "TrueDualPortINTEL"; + case SpvDecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case SpvDecorationCacheSizeINTEL: return "CacheSizeINTEL"; + case SpvDecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case SpvDecorationPrefetchINTEL: return "PrefetchINTEL"; + case SpvDecorationStallEnableINTEL: return "StallEnableINTEL"; + case SpvDecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case SpvDecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case SpvDecorationAliasScopeINTEL: return "AliasScopeINTEL"; + case SpvDecorationNoAliasINTEL: return "NoAliasINTEL"; + case SpvDecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case SpvDecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case SpvDecorationPipelineEnableINTEL: return "PipelineEnableINTEL"; + case SpvDecorationBufferLocationINTEL: return "BufferLocationINTEL"; + case SpvDecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case SpvDecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case SpvDecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case SpvDecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case SpvDecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case SpvDecorationStallFreeINTEL: return "StallFreeINTEL"; + case SpvDecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case SpvDecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case SpvDecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case SpvDecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case SpvDecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case SpvDecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case SpvDecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case SpvDecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case SpvDecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case SpvDecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case SpvDecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case SpvDecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case SpvDecorationHostAccessINTEL: return "HostAccessINTEL"; + case SpvDecorationInitModeINTEL: return "InitModeINTEL"; + case SpvDecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case SpvDecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case SpvDecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvBuiltInToString(SpvBuiltIn value) { + switch (value) { + case SpvBuiltInPosition: return "Position"; + case SpvBuiltInPointSize: return "PointSize"; + case SpvBuiltInClipDistance: return "ClipDistance"; + case SpvBuiltInCullDistance: return "CullDistance"; + case SpvBuiltInVertexId: return "VertexId"; + case SpvBuiltInInstanceId: return "InstanceId"; + case SpvBuiltInPrimitiveId: return "PrimitiveId"; + case SpvBuiltInInvocationId: return "InvocationId"; + case SpvBuiltInLayer: return "Layer"; + case SpvBuiltInViewportIndex: return "ViewportIndex"; + case SpvBuiltInTessLevelOuter: return "TessLevelOuter"; + case SpvBuiltInTessLevelInner: return "TessLevelInner"; + case SpvBuiltInTessCoord: return "TessCoord"; + case SpvBuiltInPatchVertices: return "PatchVertices"; + case SpvBuiltInFragCoord: return "FragCoord"; + case SpvBuiltInPointCoord: return "PointCoord"; + case SpvBuiltInFrontFacing: return "FrontFacing"; + case SpvBuiltInSampleId: return "SampleId"; + case SpvBuiltInSamplePosition: return "SamplePosition"; + case SpvBuiltInSampleMask: return "SampleMask"; + case SpvBuiltInFragDepth: return "FragDepth"; + case SpvBuiltInHelperInvocation: return "HelperInvocation"; + case SpvBuiltInNumWorkgroups: return "NumWorkgroups"; + case SpvBuiltInWorkgroupSize: return "WorkgroupSize"; + case SpvBuiltInWorkgroupId: return "WorkgroupId"; + case SpvBuiltInLocalInvocationId: return "LocalInvocationId"; + case SpvBuiltInGlobalInvocationId: return "GlobalInvocationId"; + case SpvBuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case SpvBuiltInWorkDim: return "WorkDim"; + case SpvBuiltInGlobalSize: return "GlobalSize"; + case SpvBuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case SpvBuiltInGlobalOffset: return "GlobalOffset"; + case SpvBuiltInGlobalLinearId: return "GlobalLinearId"; + case SpvBuiltInSubgroupSize: return "SubgroupSize"; + case SpvBuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case SpvBuiltInNumSubgroups: return "NumSubgroups"; + case SpvBuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case SpvBuiltInSubgroupId: return "SubgroupId"; + case SpvBuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case SpvBuiltInVertexIndex: return "VertexIndex"; + case SpvBuiltInInstanceIndex: return "InstanceIndex"; + case SpvBuiltInCoreIDARM: return "CoreIDARM"; + case SpvBuiltInCoreCountARM: return "CoreCountARM"; + case SpvBuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case SpvBuiltInWarpIDARM: return "WarpIDARM"; + case SpvBuiltInWarpMaxIDARM: return "WarpMaxIDARM"; + case SpvBuiltInSubgroupEqMask: return "SubgroupEqMask"; + case SpvBuiltInSubgroupGeMask: return "SubgroupGeMask"; + case SpvBuiltInSubgroupGtMask: return "SubgroupGtMask"; + case SpvBuiltInSubgroupLeMask: return "SubgroupLeMask"; + case SpvBuiltInSubgroupLtMask: return "SubgroupLtMask"; + case SpvBuiltInBaseVertex: return "BaseVertex"; + case SpvBuiltInBaseInstance: return "BaseInstance"; + case SpvBuiltInDrawIndex: return "DrawIndex"; + case SpvBuiltInPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case SpvBuiltInDeviceIndex: return "DeviceIndex"; + case SpvBuiltInViewIndex: return "ViewIndex"; + case SpvBuiltInShadingRateKHR: return "ShadingRateKHR"; + case SpvBuiltInBaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case SpvBuiltInBaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case SpvBuiltInBaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case SpvBuiltInBaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case SpvBuiltInBaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case SpvBuiltInBaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case SpvBuiltInBaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case SpvBuiltInFragStencilRefEXT: return "FragStencilRefEXT"; + case SpvBuiltInCoalescedInputCountAMDX: return "CoalescedInputCountAMDX"; + case SpvBuiltInShaderIndexAMDX: return "ShaderIndexAMDX"; + case SpvBuiltInViewportMaskNV: return "ViewportMaskNV"; + case SpvBuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case SpvBuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case SpvBuiltInPositionPerViewNV: return "PositionPerViewNV"; + case SpvBuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case SpvBuiltInFullyCoveredEXT: return "FullyCoveredEXT"; + case SpvBuiltInTaskCountNV: return "TaskCountNV"; + case SpvBuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case SpvBuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case SpvBuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case SpvBuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case SpvBuiltInLayerPerViewNV: return "LayerPerViewNV"; + case SpvBuiltInMeshViewCountNV: return "MeshViewCountNV"; + case SpvBuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case SpvBuiltInBaryCoordKHR: return "BaryCoordKHR"; + case SpvBuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case SpvBuiltInFragSizeEXT: return "FragSizeEXT"; + case SpvBuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case SpvBuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case SpvBuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case SpvBuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case SpvBuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case SpvBuiltInLaunchIdKHR: return "LaunchIdKHR"; + case SpvBuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case SpvBuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case SpvBuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case SpvBuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case SpvBuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case SpvBuiltInRayTminKHR: return "RayTminKHR"; + case SpvBuiltInRayTmaxKHR: return "RayTmaxKHR"; + case SpvBuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case SpvBuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case SpvBuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case SpvBuiltInHitTNV: return "HitTNV"; + case SpvBuiltInHitKindKHR: return "HitKindKHR"; + case SpvBuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case SpvBuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case SpvBuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case SpvBuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case SpvBuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case SpvBuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case SpvBuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case SpvBuiltInSMCountNV: return "SMCountNV"; + case SpvBuiltInWarpIDNV: return "WarpIDNV"; + case SpvBuiltInSMIDNV: return "SMIDNV"; + case SpvBuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case SpvBuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case SpvBuiltInCullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvScopeToString(SpvScope value) { + switch (value) { + case SpvScopeCrossDevice: return "CrossDevice"; + case SpvScopeDevice: return "Device"; + case SpvScopeWorkgroup: return "Workgroup"; + case SpvScopeSubgroup: return "Subgroup"; + case SpvScopeInvocation: return "Invocation"; + case SpvScopeQueueFamily: return "QueueFamily"; + case SpvScopeShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvGroupOperationToString(SpvGroupOperation value) { + switch (value) { + case SpvGroupOperationReduce: return "Reduce"; + case SpvGroupOperationInclusiveScan: return "InclusiveScan"; + case SpvGroupOperationExclusiveScan: return "ExclusiveScan"; + case SpvGroupOperationClusteredReduce: return "ClusteredReduce"; + case SpvGroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; + case SpvGroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case SpvGroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* SpvKernelEnqueueFlagsToString(SpvKernelEnqueueFlags value) { + switch (value) { + case SpvKernelEnqueueFlagsNoWait: return "NoWait"; + case SpvKernelEnqueueFlagsWaitKernel: return "WaitKernel"; + case SpvKernelEnqueueFlagsWaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* SpvCapabilityToString(SpvCapability value) { + switch (value) { + case SpvCapabilityMatrix: return "Matrix"; + case SpvCapabilityShader: return "Shader"; + case SpvCapabilityGeometry: return "Geometry"; + case SpvCapabilityTessellation: return "Tessellation"; + case SpvCapabilityAddresses: return "Addresses"; + case SpvCapabilityLinkage: return "Linkage"; + case SpvCapabilityKernel: return "Kernel"; + case SpvCapabilityVector16: return "Vector16"; + case SpvCapabilityFloat16Buffer: return "Float16Buffer"; + case SpvCapabilityFloat16: return "Float16"; + case SpvCapabilityFloat64: return "Float64"; + case SpvCapabilityInt64: return "Int64"; + case SpvCapabilityInt64Atomics: return "Int64Atomics"; + case SpvCapabilityImageBasic: return "ImageBasic"; + case SpvCapabilityImageReadWrite: return "ImageReadWrite"; + case SpvCapabilityImageMipmap: return "ImageMipmap"; + case SpvCapabilityPipes: return "Pipes"; + case SpvCapabilityGroups: return "Groups"; + case SpvCapabilityDeviceEnqueue: return "DeviceEnqueue"; + case SpvCapabilityLiteralSampler: return "LiteralSampler"; + case SpvCapabilityAtomicStorage: return "AtomicStorage"; + case SpvCapabilityInt16: return "Int16"; + case SpvCapabilityTessellationPointSize: return "TessellationPointSize"; + case SpvCapabilityGeometryPointSize: return "GeometryPointSize"; + case SpvCapabilityImageGatherExtended: return "ImageGatherExtended"; + case SpvCapabilityStorageImageMultisample: return "StorageImageMultisample"; + case SpvCapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case SpvCapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case SpvCapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case SpvCapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case SpvCapabilityClipDistance: return "ClipDistance"; + case SpvCapabilityCullDistance: return "CullDistance"; + case SpvCapabilityImageCubeArray: return "ImageCubeArray"; + case SpvCapabilitySampleRateShading: return "SampleRateShading"; + case SpvCapabilityImageRect: return "ImageRect"; + case SpvCapabilitySampledRect: return "SampledRect"; + case SpvCapabilityGenericPointer: return "GenericPointer"; + case SpvCapabilityInt8: return "Int8"; + case SpvCapabilityInputAttachment: return "InputAttachment"; + case SpvCapabilitySparseResidency: return "SparseResidency"; + case SpvCapabilityMinLod: return "MinLod"; + case SpvCapabilitySampled1D: return "Sampled1D"; + case SpvCapabilityImage1D: return "Image1D"; + case SpvCapabilitySampledCubeArray: return "SampledCubeArray"; + case SpvCapabilitySampledBuffer: return "SampledBuffer"; + case SpvCapabilityImageBuffer: return "ImageBuffer"; + case SpvCapabilityImageMSArray: return "ImageMSArray"; + case SpvCapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case SpvCapabilityImageQuery: return "ImageQuery"; + case SpvCapabilityDerivativeControl: return "DerivativeControl"; + case SpvCapabilityInterpolationFunction: return "InterpolationFunction"; + case SpvCapabilityTransformFeedback: return "TransformFeedback"; + case SpvCapabilityGeometryStreams: return "GeometryStreams"; + case SpvCapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case SpvCapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case SpvCapabilityMultiViewport: return "MultiViewport"; + case SpvCapabilitySubgroupDispatch: return "SubgroupDispatch"; + case SpvCapabilityNamedBarrier: return "NamedBarrier"; + case SpvCapabilityPipeStorage: return "PipeStorage"; + case SpvCapabilityGroupNonUniform: return "GroupNonUniform"; + case SpvCapabilityGroupNonUniformVote: return "GroupNonUniformVote"; + case SpvCapabilityGroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case SpvCapabilityGroupNonUniformBallot: return "GroupNonUniformBallot"; + case SpvCapabilityGroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case SpvCapabilityGroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case SpvCapabilityGroupNonUniformClustered: return "GroupNonUniformClustered"; + case SpvCapabilityGroupNonUniformQuad: return "GroupNonUniformQuad"; + case SpvCapabilityShaderLayer: return "ShaderLayer"; + case SpvCapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case SpvCapabilityUniformDecoration: return "UniformDecoration"; + case SpvCapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + case SpvCapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case SpvCapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case SpvCapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case SpvCapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case SpvCapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case SpvCapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; + case SpvCapabilityDrawParameters: return "DrawParameters"; + case SpvCapabilityWorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case SpvCapabilitySubgroupVoteKHR: return "SubgroupVoteKHR"; + case SpvCapabilityStorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case SpvCapabilityStorageUniform16: return "StorageUniform16"; + case SpvCapabilityStoragePushConstant16: return "StoragePushConstant16"; + case SpvCapabilityStorageInputOutput16: return "StorageInputOutput16"; + case SpvCapabilityDeviceGroup: return "DeviceGroup"; + case SpvCapabilityMultiView: return "MultiView"; + case SpvCapabilityVariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case SpvCapabilityVariablePointers: return "VariablePointers"; + case SpvCapabilityAtomicStorageOps: return "AtomicStorageOps"; + case SpvCapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case SpvCapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case SpvCapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case SpvCapabilityStoragePushConstant8: return "StoragePushConstant8"; + case SpvCapabilityDenormPreserve: return "DenormPreserve"; + case SpvCapabilityDenormFlushToZero: return "DenormFlushToZero"; + case SpvCapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case SpvCapabilityRoundingModeRTE: return "RoundingModeRTE"; + case SpvCapabilityRoundingModeRTZ: return "RoundingModeRTZ"; + case SpvCapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case SpvCapabilityRayQueryKHR: return "RayQueryKHR"; + case SpvCapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case SpvCapabilityRayTracingKHR: return "RayTracingKHR"; + case SpvCapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case SpvCapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case SpvCapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case SpvCapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case SpvCapabilityFloat16ImageAMD: return "Float16ImageAMD"; + case SpvCapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case SpvCapabilityFragmentMaskAMD: return "FragmentMaskAMD"; + case SpvCapabilityStencilExportEXT: return "StencilExportEXT"; + case SpvCapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case SpvCapabilityInt64ImageEXT: return "Int64ImageEXT"; + case SpvCapabilityShaderClockKHR: return "ShaderClockKHR"; + case SpvCapabilityShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case SpvCapabilityQuadControlKHR: return "QuadControlKHR"; + case SpvCapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case SpvCapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case SpvCapabilityShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case SpvCapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case SpvCapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case SpvCapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case SpvCapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case SpvCapabilityMeshShadingNV: return "MeshShadingNV"; + case SpvCapabilityImageFootprintNV: return "ImageFootprintNV"; + case SpvCapabilityMeshShadingEXT: return "MeshShadingEXT"; + case SpvCapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case SpvCapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case SpvCapabilityFragmentDensityEXT: return "FragmentDensityEXT"; + case SpvCapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case SpvCapabilityShaderNonUniform: return "ShaderNonUniform"; + case SpvCapabilityRuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case SpvCapabilityInputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case SpvCapabilityUniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case SpvCapabilityStorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case SpvCapabilityUniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case SpvCapabilitySampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case SpvCapabilityStorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case SpvCapabilityInputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case SpvCapabilityUniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityStorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case SpvCapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case SpvCapabilityRayTracingNV: return "RayTracingNV"; + case SpvCapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case SpvCapabilityVulkanMemoryModel: return "VulkanMemoryModel"; + case SpvCapabilityVulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case SpvCapabilityPhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case SpvCapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case SpvCapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case SpvCapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case SpvCapabilityFragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case SpvCapabilityFragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case SpvCapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case SpvCapabilityFragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case SpvCapabilityDemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case SpvCapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case SpvCapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case SpvCapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case SpvCapabilityBindlessTextureNV: return "BindlessTextureNV"; + case SpvCapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case SpvCapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case SpvCapabilityRayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case SpvCapabilityRawAccessChainsNV: return "RawAccessChainsNV"; + case SpvCapabilitySubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case SpvCapabilitySubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case SpvCapabilitySubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case SpvCapabilitySubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case SpvCapabilityRoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case SpvCapabilityFloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case SpvCapabilityIntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case SpvCapabilityFunctionPointersINTEL: return "FunctionPointersINTEL"; + case SpvCapabilityIndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case SpvCapabilityAsmINTEL: return "AsmINTEL"; + case SpvCapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case SpvCapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case SpvCapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case SpvCapabilityVectorComputeINTEL: return "VectorComputeINTEL"; + case SpvCapabilityVectorAnyINTEL: return "VectorAnyINTEL"; + case SpvCapabilityExpectAssumeKHR: return "ExpectAssumeKHR"; + case SpvCapabilitySubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case SpvCapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case SpvCapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case SpvCapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case SpvCapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case SpvCapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case SpvCapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case SpvCapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case SpvCapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case SpvCapabilityKernelAttributesINTEL: return "KernelAttributesINTEL"; + case SpvCapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case SpvCapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case SpvCapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case SpvCapabilityLoopFuseINTEL: return "LoopFuseINTEL"; + case SpvCapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case SpvCapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case SpvCapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case SpvCapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case SpvCapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case SpvCapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case SpvCapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case SpvCapabilityIOPipesINTEL: return "IOPipesINTEL"; + case SpvCapabilityBlockingPipesINTEL: return "BlockingPipesINTEL"; + case SpvCapabilityFPGARegINTEL: return "FPGARegINTEL"; + case SpvCapabilityDotProductInputAll: return "DotProductInputAll"; + case SpvCapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case SpvCapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case SpvCapabilityDotProduct: return "DotProduct"; + case SpvCapabilityRayCullMaskKHR: return "RayCullMaskKHR"; + case SpvCapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case SpvCapabilityReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case SpvCapabilityBitInstructions: return "BitInstructions"; + case SpvCapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case SpvCapabilityFloatControls2: return "FloatControls2"; + case SpvCapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case SpvCapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case SpvCapabilityLongCompositesINTEL: return "LongCompositesINTEL"; + case SpvCapabilityOptNoneINTEL: return "OptNoneINTEL"; + case SpvCapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case SpvCapabilityDebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case SpvCapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case SpvCapabilitySplitBarrierINTEL: return "SplitBarrierINTEL"; + case SpvCapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case SpvCapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case SpvCapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case SpvCapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case SpvCapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case SpvCapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case SpvCapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case SpvCapabilityGroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case SpvCapabilityMaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case SpvCapabilityCacheControlsINTEL: return "CacheControlsINTEL"; + case SpvCapabilityRegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryIntersectionToString(SpvRayQueryIntersection value) { + switch (value) { + case SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryCommittedIntersectionTypeToString(SpvRayQueryCommittedIntersectionType value) { + switch (value) { + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvRayQueryCandidateIntersectionTypeToString(SpvRayQueryCandidateIntersectionType value) { + switch (value) { + case SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvFPDenormModeToString(SpvFPDenormMode value) { + switch (value) { + case SpvFPDenormModePreserve: return "Preserve"; + case SpvFPDenormModeFlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* SpvFPOperationModeToString(SpvFPOperationMode value) { + switch (value) { + case SpvFPOperationModeIEEE: return "IEEE"; + case SpvFPOperationModeALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* SpvQuantizationModesToString(SpvQuantizationModes value) { + switch (value) { + case SpvQuantizationModesTRN: return "TRN"; + case SpvQuantizationModesTRN_ZERO: return "TRN_ZERO"; + case SpvQuantizationModesRND: return "RND"; + case SpvQuantizationModesRND_ZERO: return "RND_ZERO"; + case SpvQuantizationModesRND_INF: return "RND_INF"; + case SpvQuantizationModesRND_MIN_INF: return "RND_MIN_INF"; + case SpvQuantizationModesRND_CONV: return "RND_CONV"; + case SpvQuantizationModesRND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* SpvOverflowModesToString(SpvOverflowModes value) { + switch (value) { + case SpvOverflowModesWRAP: return "WRAP"; + case SpvOverflowModesSAT: return "SAT"; + case SpvOverflowModesSAT_ZERO: return "SAT_ZERO"; + case SpvOverflowModesSAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* SpvPackedVectorFormatToString(SpvPackedVectorFormat value) { + switch (value) { + case SpvPackedVectorFormatPackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* SpvCooperativeMatrixLayoutToString(SpvCooperativeMatrixLayout value) { + switch (value) { + case SpvCooperativeMatrixLayoutRowMajorKHR: return "RowMajorKHR"; + case SpvCooperativeMatrixLayoutColumnMajorKHR: return "ColumnMajorKHR"; + case SpvCooperativeMatrixLayoutRowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case SpvCooperativeMatrixLayoutColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* SpvCooperativeMatrixUseToString(SpvCooperativeMatrixUse value) { + switch (value) { + case SpvCooperativeMatrixUseMatrixAKHR: return "MatrixAKHR"; + case SpvCooperativeMatrixUseMatrixBKHR: return "MatrixBKHR"; + case SpvCooperativeMatrixUseMatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* SpvInitializationModeQualifierToString(SpvInitializationModeQualifier value) { + switch (value) { + case SpvInitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case SpvInitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvHostAccessQualifierToString(SpvHostAccessQualifier value) { + switch (value) { + case SpvHostAccessQualifierNoneINTEL: return "NoneINTEL"; + case SpvHostAccessQualifierReadINTEL: return "ReadINTEL"; + case SpvHostAccessQualifierWriteINTEL: return "WriteINTEL"; + case SpvHostAccessQualifierReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvLoadCacheControlToString(SpvLoadCacheControl value) { + switch (value) { + case SpvLoadCacheControlUncachedINTEL: return "UncachedINTEL"; + case SpvLoadCacheControlCachedINTEL: return "CachedINTEL"; + case SpvLoadCacheControlStreamingINTEL: return "StreamingINTEL"; + case SpvLoadCacheControlInvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case SpvLoadCacheControlConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvStoreCacheControlToString(SpvStoreCacheControl value) { + switch (value) { + case SpvStoreCacheControlUncachedINTEL: return "UncachedINTEL"; + case SpvStoreCacheControlWriteThroughINTEL: return "WriteThroughINTEL"; + case SpvStoreCacheControlWriteBackINTEL: return "WriteBackINTEL"; + case SpvStoreCacheControlStreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvNamedMaximumNumberOfRegistersToString(SpvNamedMaximumNumberOfRegisters value) { + switch (value) { + case SpvNamedMaximumNumberOfRegistersAutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* SpvOpToString(SpvOp value) { + switch (value) { + case SpvOpNop: return "OpNop"; + case SpvOpUndef: return "OpUndef"; + case SpvOpSourceContinued: return "OpSourceContinued"; + case SpvOpSource: return "OpSource"; + case SpvOpSourceExtension: return "OpSourceExtension"; + case SpvOpName: return "OpName"; + case SpvOpMemberName: return "OpMemberName"; + case SpvOpString: return "OpString"; + case SpvOpLine: return "OpLine"; + case SpvOpExtension: return "OpExtension"; + case SpvOpExtInstImport: return "OpExtInstImport"; + case SpvOpExtInst: return "OpExtInst"; + case SpvOpMemoryModel: return "OpMemoryModel"; + case SpvOpEntryPoint: return "OpEntryPoint"; + case SpvOpExecutionMode: return "OpExecutionMode"; + case SpvOpCapability: return "OpCapability"; + case SpvOpTypeVoid: return "OpTypeVoid"; + case SpvOpTypeBool: return "OpTypeBool"; + case SpvOpTypeInt: return "OpTypeInt"; + case SpvOpTypeFloat: return "OpTypeFloat"; + case SpvOpTypeVector: return "OpTypeVector"; + case SpvOpTypeMatrix: return "OpTypeMatrix"; + case SpvOpTypeImage: return "OpTypeImage"; + case SpvOpTypeSampler: return "OpTypeSampler"; + case SpvOpTypeSampledImage: return "OpTypeSampledImage"; + case SpvOpTypeArray: return "OpTypeArray"; + case SpvOpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case SpvOpTypeStruct: return "OpTypeStruct"; + case SpvOpTypeOpaque: return "OpTypeOpaque"; + case SpvOpTypePointer: return "OpTypePointer"; + case SpvOpTypeFunction: return "OpTypeFunction"; + case SpvOpTypeEvent: return "OpTypeEvent"; + case SpvOpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case SpvOpTypeReserveId: return "OpTypeReserveId"; + case SpvOpTypeQueue: return "OpTypeQueue"; + case SpvOpTypePipe: return "OpTypePipe"; + case SpvOpTypeForwardPointer: return "OpTypeForwardPointer"; + case SpvOpConstantTrue: return "OpConstantTrue"; + case SpvOpConstantFalse: return "OpConstantFalse"; + case SpvOpConstant: return "OpConstant"; + case SpvOpConstantComposite: return "OpConstantComposite"; + case SpvOpConstantSampler: return "OpConstantSampler"; + case SpvOpConstantNull: return "OpConstantNull"; + case SpvOpSpecConstantTrue: return "OpSpecConstantTrue"; + case SpvOpSpecConstantFalse: return "OpSpecConstantFalse"; + case SpvOpSpecConstant: return "OpSpecConstant"; + case SpvOpSpecConstantComposite: return "OpSpecConstantComposite"; + case SpvOpSpecConstantOp: return "OpSpecConstantOp"; + case SpvOpFunction: return "OpFunction"; + case SpvOpFunctionParameter: return "OpFunctionParameter"; + case SpvOpFunctionEnd: return "OpFunctionEnd"; + case SpvOpFunctionCall: return "OpFunctionCall"; + case SpvOpVariable: return "OpVariable"; + case SpvOpImageTexelPointer: return "OpImageTexelPointer"; + case SpvOpLoad: return "OpLoad"; + case SpvOpStore: return "OpStore"; + case SpvOpCopyMemory: return "OpCopyMemory"; + case SpvOpCopyMemorySized: return "OpCopyMemorySized"; + case SpvOpAccessChain: return "OpAccessChain"; + case SpvOpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case SpvOpPtrAccessChain: return "OpPtrAccessChain"; + case SpvOpArrayLength: return "OpArrayLength"; + case SpvOpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case SpvOpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case SpvOpDecorate: return "OpDecorate"; + case SpvOpMemberDecorate: return "OpMemberDecorate"; + case SpvOpDecorationGroup: return "OpDecorationGroup"; + case SpvOpGroupDecorate: return "OpGroupDecorate"; + case SpvOpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case SpvOpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case SpvOpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case SpvOpVectorShuffle: return "OpVectorShuffle"; + case SpvOpCompositeConstruct: return "OpCompositeConstruct"; + case SpvOpCompositeExtract: return "OpCompositeExtract"; + case SpvOpCompositeInsert: return "OpCompositeInsert"; + case SpvOpCopyObject: return "OpCopyObject"; + case SpvOpTranspose: return "OpTranspose"; + case SpvOpSampledImage: return "OpSampledImage"; + case SpvOpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case SpvOpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case SpvOpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case SpvOpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case SpvOpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case SpvOpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case SpvOpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case SpvOpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case SpvOpImageFetch: return "OpImageFetch"; + case SpvOpImageGather: return "OpImageGather"; + case SpvOpImageDrefGather: return "OpImageDrefGather"; + case SpvOpImageRead: return "OpImageRead"; + case SpvOpImageWrite: return "OpImageWrite"; + case SpvOpImage: return "OpImage"; + case SpvOpImageQueryFormat: return "OpImageQueryFormat"; + case SpvOpImageQueryOrder: return "OpImageQueryOrder"; + case SpvOpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case SpvOpImageQuerySize: return "OpImageQuerySize"; + case SpvOpImageQueryLod: return "OpImageQueryLod"; + case SpvOpImageQueryLevels: return "OpImageQueryLevels"; + case SpvOpImageQuerySamples: return "OpImageQuerySamples"; + case SpvOpConvertFToU: return "OpConvertFToU"; + case SpvOpConvertFToS: return "OpConvertFToS"; + case SpvOpConvertSToF: return "OpConvertSToF"; + case SpvOpConvertUToF: return "OpConvertUToF"; + case SpvOpUConvert: return "OpUConvert"; + case SpvOpSConvert: return "OpSConvert"; + case SpvOpFConvert: return "OpFConvert"; + case SpvOpQuantizeToF16: return "OpQuantizeToF16"; + case SpvOpConvertPtrToU: return "OpConvertPtrToU"; + case SpvOpSatConvertSToU: return "OpSatConvertSToU"; + case SpvOpSatConvertUToS: return "OpSatConvertUToS"; + case SpvOpConvertUToPtr: return "OpConvertUToPtr"; + case SpvOpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case SpvOpGenericCastToPtr: return "OpGenericCastToPtr"; + case SpvOpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case SpvOpBitcast: return "OpBitcast"; + case SpvOpSNegate: return "OpSNegate"; + case SpvOpFNegate: return "OpFNegate"; + case SpvOpIAdd: return "OpIAdd"; + case SpvOpFAdd: return "OpFAdd"; + case SpvOpISub: return "OpISub"; + case SpvOpFSub: return "OpFSub"; + case SpvOpIMul: return "OpIMul"; + case SpvOpFMul: return "OpFMul"; + case SpvOpUDiv: return "OpUDiv"; + case SpvOpSDiv: return "OpSDiv"; + case SpvOpFDiv: return "OpFDiv"; + case SpvOpUMod: return "OpUMod"; + case SpvOpSRem: return "OpSRem"; + case SpvOpSMod: return "OpSMod"; + case SpvOpFRem: return "OpFRem"; + case SpvOpFMod: return "OpFMod"; + case SpvOpVectorTimesScalar: return "OpVectorTimesScalar"; + case SpvOpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case SpvOpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case SpvOpMatrixTimesVector: return "OpMatrixTimesVector"; + case SpvOpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case SpvOpOuterProduct: return "OpOuterProduct"; + case SpvOpDot: return "OpDot"; + case SpvOpIAddCarry: return "OpIAddCarry"; + case SpvOpISubBorrow: return "OpISubBorrow"; + case SpvOpUMulExtended: return "OpUMulExtended"; + case SpvOpSMulExtended: return "OpSMulExtended"; + case SpvOpAny: return "OpAny"; + case SpvOpAll: return "OpAll"; + case SpvOpIsNan: return "OpIsNan"; + case SpvOpIsInf: return "OpIsInf"; + case SpvOpIsFinite: return "OpIsFinite"; + case SpvOpIsNormal: return "OpIsNormal"; + case SpvOpSignBitSet: return "OpSignBitSet"; + case SpvOpLessOrGreater: return "OpLessOrGreater"; + case SpvOpOrdered: return "OpOrdered"; + case SpvOpUnordered: return "OpUnordered"; + case SpvOpLogicalEqual: return "OpLogicalEqual"; + case SpvOpLogicalNotEqual: return "OpLogicalNotEqual"; + case SpvOpLogicalOr: return "OpLogicalOr"; + case SpvOpLogicalAnd: return "OpLogicalAnd"; + case SpvOpLogicalNot: return "OpLogicalNot"; + case SpvOpSelect: return "OpSelect"; + case SpvOpIEqual: return "OpIEqual"; + case SpvOpINotEqual: return "OpINotEqual"; + case SpvOpUGreaterThan: return "OpUGreaterThan"; + case SpvOpSGreaterThan: return "OpSGreaterThan"; + case SpvOpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case SpvOpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case SpvOpULessThan: return "OpULessThan"; + case SpvOpSLessThan: return "OpSLessThan"; + case SpvOpULessThanEqual: return "OpULessThanEqual"; + case SpvOpSLessThanEqual: return "OpSLessThanEqual"; + case SpvOpFOrdEqual: return "OpFOrdEqual"; + case SpvOpFUnordEqual: return "OpFUnordEqual"; + case SpvOpFOrdNotEqual: return "OpFOrdNotEqual"; + case SpvOpFUnordNotEqual: return "OpFUnordNotEqual"; + case SpvOpFOrdLessThan: return "OpFOrdLessThan"; + case SpvOpFUnordLessThan: return "OpFUnordLessThan"; + case SpvOpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case SpvOpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case SpvOpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case SpvOpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case SpvOpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case SpvOpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case SpvOpShiftRightLogical: return "OpShiftRightLogical"; + case SpvOpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case SpvOpShiftLeftLogical: return "OpShiftLeftLogical"; + case SpvOpBitwiseOr: return "OpBitwiseOr"; + case SpvOpBitwiseXor: return "OpBitwiseXor"; + case SpvOpBitwiseAnd: return "OpBitwiseAnd"; + case SpvOpNot: return "OpNot"; + case SpvOpBitFieldInsert: return "OpBitFieldInsert"; + case SpvOpBitFieldSExtract: return "OpBitFieldSExtract"; + case SpvOpBitFieldUExtract: return "OpBitFieldUExtract"; + case SpvOpBitReverse: return "OpBitReverse"; + case SpvOpBitCount: return "OpBitCount"; + case SpvOpDPdx: return "OpDPdx"; + case SpvOpDPdy: return "OpDPdy"; + case SpvOpFwidth: return "OpFwidth"; + case SpvOpDPdxFine: return "OpDPdxFine"; + case SpvOpDPdyFine: return "OpDPdyFine"; + case SpvOpFwidthFine: return "OpFwidthFine"; + case SpvOpDPdxCoarse: return "OpDPdxCoarse"; + case SpvOpDPdyCoarse: return "OpDPdyCoarse"; + case SpvOpFwidthCoarse: return "OpFwidthCoarse"; + case SpvOpEmitVertex: return "OpEmitVertex"; + case SpvOpEndPrimitive: return "OpEndPrimitive"; + case SpvOpEmitStreamVertex: return "OpEmitStreamVertex"; + case SpvOpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case SpvOpControlBarrier: return "OpControlBarrier"; + case SpvOpMemoryBarrier: return "OpMemoryBarrier"; + case SpvOpAtomicLoad: return "OpAtomicLoad"; + case SpvOpAtomicStore: return "OpAtomicStore"; + case SpvOpAtomicExchange: return "OpAtomicExchange"; + case SpvOpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case SpvOpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case SpvOpAtomicIIncrement: return "OpAtomicIIncrement"; + case SpvOpAtomicIDecrement: return "OpAtomicIDecrement"; + case SpvOpAtomicIAdd: return "OpAtomicIAdd"; + case SpvOpAtomicISub: return "OpAtomicISub"; + case SpvOpAtomicSMin: return "OpAtomicSMin"; + case SpvOpAtomicUMin: return "OpAtomicUMin"; + case SpvOpAtomicSMax: return "OpAtomicSMax"; + case SpvOpAtomicUMax: return "OpAtomicUMax"; + case SpvOpAtomicAnd: return "OpAtomicAnd"; + case SpvOpAtomicOr: return "OpAtomicOr"; + case SpvOpAtomicXor: return "OpAtomicXor"; + case SpvOpPhi: return "OpPhi"; + case SpvOpLoopMerge: return "OpLoopMerge"; + case SpvOpSelectionMerge: return "OpSelectionMerge"; + case SpvOpLabel: return "OpLabel"; + case SpvOpBranch: return "OpBranch"; + case SpvOpBranchConditional: return "OpBranchConditional"; + case SpvOpSwitch: return "OpSwitch"; + case SpvOpKill: return "OpKill"; + case SpvOpReturn: return "OpReturn"; + case SpvOpReturnValue: return "OpReturnValue"; + case SpvOpUnreachable: return "OpUnreachable"; + case SpvOpLifetimeStart: return "OpLifetimeStart"; + case SpvOpLifetimeStop: return "OpLifetimeStop"; + case SpvOpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case SpvOpGroupWaitEvents: return "OpGroupWaitEvents"; + case SpvOpGroupAll: return "OpGroupAll"; + case SpvOpGroupAny: return "OpGroupAny"; + case SpvOpGroupBroadcast: return "OpGroupBroadcast"; + case SpvOpGroupIAdd: return "OpGroupIAdd"; + case SpvOpGroupFAdd: return "OpGroupFAdd"; + case SpvOpGroupFMin: return "OpGroupFMin"; + case SpvOpGroupUMin: return "OpGroupUMin"; + case SpvOpGroupSMin: return "OpGroupSMin"; + case SpvOpGroupFMax: return "OpGroupFMax"; + case SpvOpGroupUMax: return "OpGroupUMax"; + case SpvOpGroupSMax: return "OpGroupSMax"; + case SpvOpReadPipe: return "OpReadPipe"; + case SpvOpWritePipe: return "OpWritePipe"; + case SpvOpReservedReadPipe: return "OpReservedReadPipe"; + case SpvOpReservedWritePipe: return "OpReservedWritePipe"; + case SpvOpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case SpvOpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case SpvOpCommitReadPipe: return "OpCommitReadPipe"; + case SpvOpCommitWritePipe: return "OpCommitWritePipe"; + case SpvOpIsValidReserveId: return "OpIsValidReserveId"; + case SpvOpGetNumPipePackets: return "OpGetNumPipePackets"; + case SpvOpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case SpvOpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case SpvOpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case SpvOpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case SpvOpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case SpvOpEnqueueMarker: return "OpEnqueueMarker"; + case SpvOpEnqueueKernel: return "OpEnqueueKernel"; + case SpvOpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case SpvOpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case SpvOpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case SpvOpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case SpvOpRetainEvent: return "OpRetainEvent"; + case SpvOpReleaseEvent: return "OpReleaseEvent"; + case SpvOpCreateUserEvent: return "OpCreateUserEvent"; + case SpvOpIsValidEvent: return "OpIsValidEvent"; + case SpvOpSetUserEventStatus: return "OpSetUserEventStatus"; + case SpvOpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case SpvOpGetDefaultQueue: return "OpGetDefaultQueue"; + case SpvOpBuildNDRange: return "OpBuildNDRange"; + case SpvOpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case SpvOpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case SpvOpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case SpvOpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case SpvOpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case SpvOpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case SpvOpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case SpvOpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case SpvOpImageSparseFetch: return "OpImageSparseFetch"; + case SpvOpImageSparseGather: return "OpImageSparseGather"; + case SpvOpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case SpvOpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case SpvOpNoLine: return "OpNoLine"; + case SpvOpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case SpvOpAtomicFlagClear: return "OpAtomicFlagClear"; + case SpvOpImageSparseRead: return "OpImageSparseRead"; + case SpvOpSizeOf: return "OpSizeOf"; + case SpvOpTypePipeStorage: return "OpTypePipeStorage"; + case SpvOpConstantPipeStorage: return "OpConstantPipeStorage"; + case SpvOpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case SpvOpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case SpvOpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case SpvOpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case SpvOpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case SpvOpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case SpvOpModuleProcessed: return "OpModuleProcessed"; + case SpvOpExecutionModeId: return "OpExecutionModeId"; + case SpvOpDecorateId: return "OpDecorateId"; + case SpvOpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case SpvOpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case SpvOpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case SpvOpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case SpvOpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case SpvOpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case SpvOpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case SpvOpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case SpvOpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case SpvOpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case SpvOpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case SpvOpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case SpvOpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case SpvOpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case SpvOpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case SpvOpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case SpvOpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case SpvOpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case SpvOpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case SpvOpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case SpvOpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case SpvOpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case SpvOpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case SpvOpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case SpvOpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case SpvOpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case SpvOpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case SpvOpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case SpvOpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case SpvOpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case SpvOpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case SpvOpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case SpvOpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case SpvOpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case SpvOpCopyLogical: return "OpCopyLogical"; + case SpvOpPtrEqual: return "OpPtrEqual"; + case SpvOpPtrNotEqual: return "OpPtrNotEqual"; + case SpvOpPtrDiff: return "OpPtrDiff"; + case SpvOpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case SpvOpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case SpvOpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case SpvOpTerminateInvocation: return "OpTerminateInvocation"; + case SpvOpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case SpvOpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case SpvOpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case SpvOpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case SpvOpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case SpvOpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case SpvOpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case SpvOpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case SpvOpTraceRayKHR: return "OpTraceRayKHR"; + case SpvOpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case SpvOpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case SpvOpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case SpvOpTerminateRayKHR: return "OpTerminateRayKHR"; + case SpvOpSDot: return "OpSDot"; + case SpvOpUDot: return "OpUDot"; + case SpvOpSUDot: return "OpSUDot"; + case SpvOpSDotAccSat: return "OpSDotAccSat"; + case SpvOpUDotAccSat: return "OpUDotAccSat"; + case SpvOpSUDotAccSat: return "OpSUDotAccSat"; + case SpvOpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case SpvOpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case SpvOpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case SpvOpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case SpvOpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case SpvOpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case SpvOpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case SpvOpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case SpvOpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case SpvOpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case SpvOpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case SpvOpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case SpvOpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case SpvOpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case SpvOpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case SpvOpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case SpvOpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case SpvOpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case SpvOpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case SpvOpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case SpvOpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case SpvOpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case SpvOpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case SpvOpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case SpvOpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case SpvOpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case SpvOpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case SpvOpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case SpvOpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case SpvOpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case SpvOpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case SpvOpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case SpvOpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case SpvOpReadClockKHR: return "OpReadClockKHR"; + case SpvOpFinalizeNodePayloadsAMDX: return "OpFinalizeNodePayloadsAMDX"; + case SpvOpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case SpvOpInitializeNodePayloadsAMDX: return "OpInitializeNodePayloadsAMDX"; + case SpvOpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case SpvOpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case SpvOpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case SpvOpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case SpvOpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case SpvOpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case SpvOpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case SpvOpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case SpvOpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case SpvOpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case SpvOpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case SpvOpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case SpvOpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case SpvOpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case SpvOpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case SpvOpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case SpvOpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case SpvOpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case SpvOpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case SpvOpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case SpvOpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case SpvOpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case SpvOpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case SpvOpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case SpvOpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case SpvOpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case SpvOpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case SpvOpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case SpvOpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case SpvOpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case SpvOpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case SpvOpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case SpvOpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case SpvOpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case SpvOpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case SpvOpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case SpvOpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case SpvOpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case SpvOpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case SpvOpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case SpvOpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case SpvOpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case SpvOpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case SpvOpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case SpvOpTerminateRayNV: return "OpTerminateRayNV"; + case SpvOpTraceNV: return "OpTraceNV"; + case SpvOpTraceMotionNV: return "OpTraceMotionNV"; + case SpvOpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case SpvOpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case SpvOpExecuteCallableNV: return "OpExecuteCallableNV"; + case SpvOpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case SpvOpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case SpvOpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case SpvOpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case SpvOpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case SpvOpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case SpvOpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case SpvOpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case SpvOpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case SpvOpConvertUToImageNV: return "OpConvertUToImageNV"; + case SpvOpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case SpvOpConvertImageToUNV: return "OpConvertImageToUNV"; + case SpvOpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case SpvOpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case SpvOpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case SpvOpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case SpvOpRawAccessChainNV: return "OpRawAccessChainNV"; + case SpvOpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case SpvOpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case SpvOpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case SpvOpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case SpvOpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case SpvOpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case SpvOpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case SpvOpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case SpvOpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case SpvOpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case SpvOpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case SpvOpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case SpvOpAbsISubINTEL: return "OpAbsISubINTEL"; + case SpvOpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case SpvOpIAddSatINTEL: return "OpIAddSatINTEL"; + case SpvOpUAddSatINTEL: return "OpUAddSatINTEL"; + case SpvOpIAverageINTEL: return "OpIAverageINTEL"; + case SpvOpUAverageINTEL: return "OpUAverageINTEL"; + case SpvOpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case SpvOpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case SpvOpISubSatINTEL: return "OpISubSatINTEL"; + case SpvOpUSubSatINTEL: return "OpUSubSatINTEL"; + case SpvOpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case SpvOpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case SpvOpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case SpvOpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case SpvOpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case SpvOpAsmINTEL: return "OpAsmINTEL"; + case SpvOpAsmCallINTEL: return "OpAsmCallINTEL"; + case SpvOpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case SpvOpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case SpvOpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case SpvOpExpectKHR: return "OpExpectKHR"; + case SpvOpDecorateString: return "OpDecorateString"; + case SpvOpMemberDecorateString: return "OpMemberDecorateString"; + case SpvOpVmeImageINTEL: return "OpVmeImageINTEL"; + case SpvOpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case SpvOpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case SpvOpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case SpvOpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case SpvOpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case SpvOpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case SpvOpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case SpvOpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case SpvOpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case SpvOpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case SpvOpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case SpvOpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case SpvOpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case SpvOpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case SpvOpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case SpvOpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case SpvOpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case SpvOpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case SpvOpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case SpvOpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case SpvOpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case SpvOpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case SpvOpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case SpvOpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case SpvOpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case SpvOpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case SpvOpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case SpvOpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case SpvOpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case SpvOpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case SpvOpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case SpvOpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case SpvOpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case SpvOpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case SpvOpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case SpvOpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case SpvOpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case SpvOpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case SpvOpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case SpvOpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case SpvOpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case SpvOpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case SpvOpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case SpvOpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case SpvOpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case SpvOpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case SpvOpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case SpvOpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case SpvOpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case SpvOpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case SpvOpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case SpvOpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case SpvOpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case SpvOpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case SpvOpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case SpvOpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case SpvOpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case SpvOpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case SpvOpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case SpvOpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case SpvOpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case SpvOpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case SpvOpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case SpvOpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case SpvOpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case SpvOpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case SpvOpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case SpvOpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case SpvOpLoopControlINTEL: return "OpLoopControlINTEL"; + case SpvOpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case SpvOpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case SpvOpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case SpvOpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case SpvOpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case SpvOpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case SpvOpFixedSinINTEL: return "OpFixedSinINTEL"; + case SpvOpFixedCosINTEL: return "OpFixedCosINTEL"; + case SpvOpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case SpvOpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case SpvOpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case SpvOpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case SpvOpFixedLogINTEL: return "OpFixedLogINTEL"; + case SpvOpFixedExpINTEL: return "OpFixedExpINTEL"; + case SpvOpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case SpvOpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case SpvOpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case SpvOpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case SpvOpFPGARegINTEL: return "OpFPGARegINTEL"; + case SpvOpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case SpvOpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case SpvOpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case SpvOpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case SpvOpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case SpvOpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case SpvOpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case SpvOpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case SpvOpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case SpvOpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case SpvOpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case SpvOpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case SpvOpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case SpvOpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case SpvOpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case SpvOpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case SpvOpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case SpvOpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case SpvOpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case SpvOpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case SpvOpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case SpvOpGroupIMulKHR: return "OpGroupIMulKHR"; + case SpvOpGroupFMulKHR: return "OpGroupFMulKHR"; + case SpvOpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case SpvOpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case SpvOpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case SpvOpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case SpvOpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case SpvOpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case SpvOpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case SpvOpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + #endif /* SPV_ENABLE_UTILITY_CODE */ #endif diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11 b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11 index 32f209f..25177a4 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11 +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.hpp11 @@ -215,6 +215,9 @@ enum class ExecutionMode : unsigned { StreamingInterfaceINTEL = 6154, RegisterMapInterfaceINTEL = 6160, NamedBarrierCountINTEL = 6417, + MaximumRegistersINTEL = 6461, + MaximumRegistersIdINTEL = 6462, + NamedMaximumRegistersINTEL = 6463, Max = 0x7fffffff, }; @@ -1042,6 +1045,7 @@ enum class Capability : unsigned { TileImageColorReadAccessEXT = 4166, TileImageDepthReadAccessEXT = 4167, TileImageStencilReadAccessEXT = 4168, + CooperativeMatrixLayoutsARM = 4201, FragmentShadingRateKHR = 4422, SubgroupBallotKHR = 4423, DrawParameters = 4427, @@ -1152,6 +1156,7 @@ enum class Capability : unsigned { RayQueryPositionFetchKHR = 5391, AtomicFloat16VectorNV = 5404, RayTracingDisplacementMicromapNV = 5409, + RawAccessChainsNV = 5414, SubgroupShuffleINTEL = 5568, SubgroupBufferBlockIOINTEL = 5569, SubgroupImageBlockIOINTEL = 5570, @@ -1204,6 +1209,7 @@ enum class Capability : unsigned { DotProductKHR = 6019, RayCullMaskKHR = 6020, CooperativeMatrixKHR = 6022, + ReplicatedCompositesEXT = 6024, BitInstructions = 6025, GroupNonUniformRotateKHR = 6026, FloatControls2 = 6029, @@ -1225,6 +1231,7 @@ enum class Capability : unsigned { GroupUniformArithmeticKHR = 6400, MaskedGatherScatterINTEL = 6427, CacheControlsINTEL = 6441, + RegisterLimitsINTEL = 6460, Max = 0x7fffffff, }; @@ -1352,6 +1359,8 @@ enum class CooperativeMatrixOperandsMask : unsigned { enum class CooperativeMatrixLayout : unsigned { RowMajorKHR = 0, ColumnMajorKHR = 1, + RowBlockedInterleavedARM = 4202, + ColumnBlockedInterleavedARM = 4203, Max = 0x7fffffff, }; @@ -1393,6 +1402,23 @@ enum class StoreCacheControl : unsigned { Max = 0x7fffffff, }; +enum class NamedMaximumNumberOfRegisters : unsigned { + AutoINTEL = 0, + Max = 0x7fffffff, +}; + +enum class RawAccessChainOperandsShift : unsigned { + RobustnessPerComponentNV = 0, + RobustnessPerElementNV = 1, + Max = 0x7fffffff, +}; + +enum class RawAccessChainOperandsMask : unsigned { + MaskNone = 0, + RobustnessPerComponentNV = 0x00000001, + RobustnessPerElementNV = 0x00000002, +}; + enum class Op : unsigned { OpNop = 0, OpUndef = 1, @@ -1749,6 +1775,7 @@ enum class Op : unsigned { OpSubgroupAllEqualKHR = 4430, OpGroupNonUniformRotateKHR = 4431, OpSubgroupReadInvocationKHR = 4432, + OpExtInstWithForwardRefsKHR = 4433, OpTraceRayKHR = 4445, OpExecuteCallableKHR = 4446, OpConvertUToAccelerationStructureKHR = 4447, @@ -1771,6 +1798,9 @@ enum class Op : unsigned { OpCooperativeMatrixStoreKHR = 4458, OpCooperativeMatrixMulAddKHR = 4459, OpCooperativeMatrixLengthKHR = 4460, + OpConstantCompositeReplicateEXT = 4461, + OpSpecConstantCompositeReplicateEXT = 4462, + OpCompositeConstructReplicateEXT = 4463, OpTypeRayQueryKHR = 4472, OpRayQueryInitializeKHR = 4473, OpRayQueryTerminateKHR = 4474, @@ -1870,6 +1900,7 @@ enum class Op : unsigned { OpConvertUToSampledImageNV = 5395, OpConvertSampledImageToUNV = 5396, OpSamplerImageAddressingModeNV = 5397, + OpRawAccessChainNV = 5398, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -2492,6 +2523,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; case Op::OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case Op::OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpExtInstWithForwardRefsKHR: *hasResult = true; *hasResultType = true; break; case Op::OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; case Op::OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; case Op::OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; @@ -2508,6 +2540,9 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; case Op::OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; case Op::OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case Op::OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break; + case Op::OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break; case Op::OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case Op::OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case Op::OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; @@ -2579,14 +2614,14 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; case Op::OpFetchMicroTriangleVertexPositionNV: *hasResult = true; *hasResultType = true; break; case Op::OpFetchMicroTriangleVertexBarycentricNV: *hasResult = true; *hasResultType = true; break; - case Op::OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case Op::OpReportIntersectionKHR: *hasResult = true; *hasResultType = true; break; 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::OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; - case Op::OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case Op::OpTypeAccelerationStructureKHR: *hasResult = true; *hasResultType = false; break; case Op::OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case Op::OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; case Op::OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; @@ -2604,6 +2639,7 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; case Op::OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; case Op::OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case Op::OpRawAccessChainNV: *hasResult = true; *hasResultType = true; break; case Op::OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; case Op::OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; case Op::OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; @@ -2860,6 +2896,1787 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case Op::OpMaskedScatterINTEL: *hasResult = false; *hasResultType = false; break; } } +inline const char* SourceLanguageToString(SourceLanguage value) { + switch (value) { + case SourceLanguageUnknown: return "Unknown"; + case SourceLanguageESSL: return "ESSL"; + case SourceLanguageGLSL: return "GLSL"; + case SourceLanguageOpenCL_C: return "OpenCL_C"; + case SourceLanguageOpenCL_CPP: return "OpenCL_CPP"; + case SourceLanguageHLSL: return "HLSL"; + case SourceLanguageCPP_for_OpenCL: return "CPP_for_OpenCL"; + case SourceLanguageSYCL: return "SYCL"; + case SourceLanguageHERO_C: return "HERO_C"; + case SourceLanguageNZSL: return "NZSL"; + case SourceLanguageWGSL: return "WGSL"; + case SourceLanguageSlang: return "Slang"; + case SourceLanguageZig: return "Zig"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModelToString(ExecutionModel value) { + switch (value) { + case ExecutionModelVertex: return "Vertex"; + case ExecutionModelTessellationControl: return "TessellationControl"; + case ExecutionModelTessellationEvaluation: return "TessellationEvaluation"; + case ExecutionModelGeometry: return "Geometry"; + case ExecutionModelFragment: return "Fragment"; + case ExecutionModelGLCompute: return "GLCompute"; + case ExecutionModelKernel: return "Kernel"; + case ExecutionModelTaskNV: return "TaskNV"; + case ExecutionModelMeshNV: return "MeshNV"; + case ExecutionModelRayGenerationKHR: return "RayGenerationKHR"; + case ExecutionModelIntersectionKHR: return "IntersectionKHR"; + case ExecutionModelAnyHitKHR: return "AnyHitKHR"; + case ExecutionModelClosestHitKHR: return "ClosestHitKHR"; + case ExecutionModelMissKHR: return "MissKHR"; + case ExecutionModelCallableKHR: return "CallableKHR"; + case ExecutionModelTaskEXT: return "TaskEXT"; + case ExecutionModelMeshEXT: return "MeshEXT"; + default: return "Unknown"; + } +} + +inline const char* AddressingModelToString(AddressingModel value) { + switch (value) { + case AddressingModelLogical: return "Logical"; + case AddressingModelPhysical32: return "Physical32"; + case AddressingModelPhysical64: return "Physical64"; + case AddressingModelPhysicalStorageBuffer64: return "PhysicalStorageBuffer64"; + default: return "Unknown"; + } +} + +inline const char* MemoryModelToString(MemoryModel value) { + switch (value) { + case MemoryModelSimple: return "Simple"; + case MemoryModelGLSL450: return "GLSL450"; + case MemoryModelOpenCL: return "OpenCL"; + case MemoryModelVulkan: return "Vulkan"; + default: return "Unknown"; + } +} + +inline const char* ExecutionModeToString(ExecutionMode value) { + switch (value) { + case ExecutionModeInvocations: return "Invocations"; + case ExecutionModeSpacingEqual: return "SpacingEqual"; + case ExecutionModeSpacingFractionalEven: return "SpacingFractionalEven"; + case ExecutionModeSpacingFractionalOdd: return "SpacingFractionalOdd"; + case ExecutionModeVertexOrderCw: return "VertexOrderCw"; + case ExecutionModeVertexOrderCcw: return "VertexOrderCcw"; + case ExecutionModePixelCenterInteger: return "PixelCenterInteger"; + case ExecutionModeOriginUpperLeft: return "OriginUpperLeft"; + case ExecutionModeOriginLowerLeft: return "OriginLowerLeft"; + case ExecutionModeEarlyFragmentTests: return "EarlyFragmentTests"; + case ExecutionModePointMode: return "PointMode"; + case ExecutionModeXfb: return "Xfb"; + case ExecutionModeDepthReplacing: return "DepthReplacing"; + case ExecutionModeDepthGreater: return "DepthGreater"; + case ExecutionModeDepthLess: return "DepthLess"; + case ExecutionModeDepthUnchanged: return "DepthUnchanged"; + case ExecutionModeLocalSize: return "LocalSize"; + case ExecutionModeLocalSizeHint: return "LocalSizeHint"; + case ExecutionModeInputPoints: return "InputPoints"; + case ExecutionModeInputLines: return "InputLines"; + case ExecutionModeInputLinesAdjacency: return "InputLinesAdjacency"; + case ExecutionModeTriangles: return "Triangles"; + case ExecutionModeInputTrianglesAdjacency: return "InputTrianglesAdjacency"; + case ExecutionModeQuads: return "Quads"; + case ExecutionModeIsolines: return "Isolines"; + case ExecutionModeOutputVertices: return "OutputVertices"; + case ExecutionModeOutputPoints: return "OutputPoints"; + case ExecutionModeOutputLineStrip: return "OutputLineStrip"; + case ExecutionModeOutputTriangleStrip: return "OutputTriangleStrip"; + case ExecutionModeVecTypeHint: return "VecTypeHint"; + case ExecutionModeContractionOff: return "ContractionOff"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlowKHR"; + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionModeCoalescingAMDX: return "CoalescingAMDX"; + case ExecutionModeMaxNodeRecursionAMDX: return "MaxNodeRecursionAMDX"; + case ExecutionModeStaticNumWorkgroupsAMDX: return "StaticNumWorkgroupsAMDX"; + case ExecutionModeShaderIndexAMDX: return "ShaderIndexAMDX"; + case ExecutionModeMaxNumWorkgroupsAMDX: return "MaxNumWorkgroupsAMDX"; + case ExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case ExecutionModeStencilRefGreaterFrontAMD: return "StencilRefGreaterFrontAMD"; + case ExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case ExecutionModeStencilRefUnchangedBackAMD: return "StencilRefUnchangedBackAMD"; + case ExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case ExecutionModeStencilRefLessBackAMD: return "StencilRefLessBackAMD"; + case ExecutionModeQuadDerivativesKHR: return "QuadDerivativesKHR"; + case ExecutionModeRequireFullQuadsKHR: return "RequireFullQuadsKHR"; + case ExecutionModeOutputLinesEXT: return "OutputLinesEXT"; + case ExecutionModeOutputPrimitivesEXT: return "OutputPrimitivesEXT"; + case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case ExecutionModeOutputTrianglesEXT: return "OutputTrianglesEXT"; + case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; + case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; + case ExecutionModeSampleInterlockOrderedEXT: return "SampleInterlockOrderedEXT"; + case ExecutionModeSampleInterlockUnorderedEXT: return "SampleInterlockUnorderedEXT"; + case ExecutionModeShadingRateInterlockOrderedEXT: return "ShadingRateInterlockOrderedEXT"; + case ExecutionModeShadingRateInterlockUnorderedEXT: return "ShadingRateInterlockUnorderedEXT"; + case ExecutionModeSharedLocalMemorySizeINTEL: return "SharedLocalMemorySizeINTEL"; + case ExecutionModeRoundingModeRTPINTEL: return "RoundingModeRTPINTEL"; + case ExecutionModeRoundingModeRTNINTEL: return "RoundingModeRTNINTEL"; + case ExecutionModeFloatingPointModeALTINTEL: return "FloatingPointModeALTINTEL"; + case ExecutionModeFloatingPointModeIEEEINTEL: return "FloatingPointModeIEEEINTEL"; + case ExecutionModeMaxWorkgroupSizeINTEL: return "MaxWorkgroupSizeINTEL"; + case ExecutionModeMaxWorkDimINTEL: return "MaxWorkDimINTEL"; + case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; + case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionModeSchedulerTargetFmaxMhzINTEL: return "SchedulerTargetFmaxMhzINTEL"; + case ExecutionModeMaximallyReconvergesKHR: return "MaximallyReconvergesKHR"; + case ExecutionModeFPFastMathDefault: return "FPFastMathDefault"; + case ExecutionModeStreamingInterfaceINTEL: return "StreamingInterfaceINTEL"; + case ExecutionModeRegisterMapInterfaceINTEL: return "RegisterMapInterfaceINTEL"; + case ExecutionModeNamedBarrierCountINTEL: return "NamedBarrierCountINTEL"; + case ExecutionModeMaximumRegistersINTEL: return "MaximumRegistersINTEL"; + case ExecutionModeMaximumRegistersIdINTEL: return "MaximumRegistersIdINTEL"; + case ExecutionModeNamedMaximumRegistersINTEL: return "NamedMaximumRegistersINTEL"; + default: return "Unknown"; + } +} + +inline const char* StorageClassToString(StorageClass value) { + switch (value) { + case StorageClassUniformConstant: return "UniformConstant"; + case StorageClassInput: return "Input"; + case StorageClassUniform: return "Uniform"; + case StorageClassOutput: return "Output"; + case StorageClassWorkgroup: return "Workgroup"; + case StorageClassCrossWorkgroup: return "CrossWorkgroup"; + case StorageClassPrivate: return "Private"; + case StorageClassFunction: return "Function"; + case StorageClassGeneric: return "Generic"; + case StorageClassPushConstant: return "PushConstant"; + case StorageClassAtomicCounter: return "AtomicCounter"; + case StorageClassImage: return "Image"; + case StorageClassStorageBuffer: return "StorageBuffer"; + case StorageClassTileImageEXT: return "TileImageEXT"; + case StorageClassNodePayloadAMDX: return "NodePayloadAMDX"; + case StorageClassNodeOutputPayloadAMDX: return "NodeOutputPayloadAMDX"; + case StorageClassCallableDataKHR: return "CallableDataKHR"; + case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; + case StorageClassRayPayloadKHR: return "RayPayloadKHR"; + case StorageClassHitAttributeKHR: return "HitAttributeKHR"; + case StorageClassIncomingRayPayloadKHR: return "IncomingRayPayloadKHR"; + case StorageClassShaderRecordBufferKHR: return "ShaderRecordBufferKHR"; + case StorageClassPhysicalStorageBuffer: return "PhysicalStorageBuffer"; + case StorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case StorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case StorageClassCodeSectionINTEL: return "CodeSectionINTEL"; + case StorageClassDeviceOnlyINTEL: return "DeviceOnlyINTEL"; + case StorageClassHostOnlyINTEL: return "HostOnlyINTEL"; + default: return "Unknown"; + } +} + +inline const char* DimToString(Dim value) { + switch (value) { + case Dim1D: return "1D"; + case Dim2D: return "2D"; + case Dim3D: return "3D"; + case DimCube: return "Cube"; + case DimRect: return "Rect"; + case DimBuffer: return "Buffer"; + case DimSubpassData: return "SubpassData"; + case DimTileImageDataEXT: return "TileImageDataEXT"; + default: return "Unknown"; + } +} + +inline const char* SamplerAddressingModeToString(SamplerAddressingMode value) { + switch (value) { + case SamplerAddressingModeNone: return "None"; + case SamplerAddressingModeClampToEdge: return "ClampToEdge"; + case SamplerAddressingModeClamp: return "Clamp"; + case SamplerAddressingModeRepeat: return "Repeat"; + case SamplerAddressingModeRepeatMirrored: return "RepeatMirrored"; + default: return "Unknown"; + } +} + +inline const char* SamplerFilterModeToString(SamplerFilterMode value) { + switch (value) { + case SamplerFilterModeNearest: return "Nearest"; + case SamplerFilterModeLinear: return "Linear"; + default: return "Unknown"; + } +} + +inline const char* ImageFormatToString(ImageFormat value) { + switch (value) { + case ImageFormatUnknown: return "Unknown"; + case ImageFormatRgba32f: return "Rgba32f"; + case ImageFormatRgba16f: return "Rgba16f"; + case ImageFormatR32f: return "R32f"; + case ImageFormatRgba8: return "Rgba8"; + case ImageFormatRgba8Snorm: return "Rgba8Snorm"; + case ImageFormatRg32f: return "Rg32f"; + case ImageFormatRg16f: return "Rg16f"; + case ImageFormatR11fG11fB10f: return "R11fG11fB10f"; + case ImageFormatR16f: return "R16f"; + case ImageFormatRgba16: return "Rgba16"; + case ImageFormatRgb10A2: return "Rgb10A2"; + case ImageFormatRg16: return "Rg16"; + case ImageFormatRg8: return "Rg8"; + case ImageFormatR16: return "R16"; + case ImageFormatR8: return "R8"; + case ImageFormatRgba16Snorm: return "Rgba16Snorm"; + case ImageFormatRg16Snorm: return "Rg16Snorm"; + case ImageFormatRg8Snorm: return "Rg8Snorm"; + case ImageFormatR16Snorm: return "R16Snorm"; + case ImageFormatR8Snorm: return "R8Snorm"; + case ImageFormatRgba32i: return "Rgba32i"; + case ImageFormatRgba16i: return "Rgba16i"; + case ImageFormatRgba8i: return "Rgba8i"; + case ImageFormatR32i: return "R32i"; + case ImageFormatRg32i: return "Rg32i"; + case ImageFormatRg16i: return "Rg16i"; + case ImageFormatRg8i: return "Rg8i"; + case ImageFormatR16i: return "R16i"; + case ImageFormatR8i: return "R8i"; + case ImageFormatRgba32ui: return "Rgba32ui"; + case ImageFormatRgba16ui: return "Rgba16ui"; + case ImageFormatRgba8ui: return "Rgba8ui"; + case ImageFormatR32ui: return "R32ui"; + case ImageFormatRgb10a2ui: return "Rgb10a2ui"; + case ImageFormatRg32ui: return "Rg32ui"; + case ImageFormatRg16ui: return "Rg16ui"; + case ImageFormatRg8ui: return "Rg8ui"; + case ImageFormatR16ui: return "R16ui"; + case ImageFormatR8ui: return "R8ui"; + case ImageFormatR64ui: return "R64ui"; + case ImageFormatR64i: return "R64i"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelOrderToString(ImageChannelOrder value) { + switch (value) { + case ImageChannelOrderR: return "R"; + case ImageChannelOrderA: return "A"; + case ImageChannelOrderRG: return "RG"; + case ImageChannelOrderRA: return "RA"; + case ImageChannelOrderRGB: return "RGB"; + case ImageChannelOrderRGBA: return "RGBA"; + case ImageChannelOrderBGRA: return "BGRA"; + case ImageChannelOrderARGB: return "ARGB"; + case ImageChannelOrderIntensity: return "Intensity"; + case ImageChannelOrderLuminance: return "Luminance"; + case ImageChannelOrderRx: return "Rx"; + case ImageChannelOrderRGx: return "RGx"; + case ImageChannelOrderRGBx: return "RGBx"; + case ImageChannelOrderDepth: return "Depth"; + case ImageChannelOrderDepthStencil: return "DepthStencil"; + case ImageChannelOrdersRGB: return "sRGB"; + case ImageChannelOrdersRGBx: return "sRGBx"; + case ImageChannelOrdersRGBA: return "sRGBA"; + case ImageChannelOrdersBGRA: return "sBGRA"; + case ImageChannelOrderABGR: return "ABGR"; + default: return "Unknown"; + } +} + +inline const char* ImageChannelDataTypeToString(ImageChannelDataType value) { + switch (value) { + case ImageChannelDataTypeSnormInt8: return "SnormInt8"; + case ImageChannelDataTypeSnormInt16: return "SnormInt16"; + case ImageChannelDataTypeUnormInt8: return "UnormInt8"; + case ImageChannelDataTypeUnormInt16: return "UnormInt16"; + case ImageChannelDataTypeUnormShort565: return "UnormShort565"; + case ImageChannelDataTypeUnormShort555: return "UnormShort555"; + case ImageChannelDataTypeUnormInt101010: return "UnormInt101010"; + case ImageChannelDataTypeSignedInt8: return "SignedInt8"; + case ImageChannelDataTypeSignedInt16: return "SignedInt16"; + case ImageChannelDataTypeSignedInt32: return "SignedInt32"; + case ImageChannelDataTypeUnsignedInt8: return "UnsignedInt8"; + case ImageChannelDataTypeUnsignedInt16: return "UnsignedInt16"; + case ImageChannelDataTypeUnsignedInt32: return "UnsignedInt32"; + case ImageChannelDataTypeHalfFloat: return "HalfFloat"; + case ImageChannelDataTypeFloat: return "Float"; + case ImageChannelDataTypeUnormInt24: return "UnormInt24"; + case ImageChannelDataTypeUnormInt101010_2: return "UnormInt101010_2"; + case ImageChannelDataTypeUnsignedIntRaw10EXT: return "UnsignedIntRaw10EXT"; + case ImageChannelDataTypeUnsignedIntRaw12EXT: return "UnsignedIntRaw12EXT"; + default: return "Unknown"; + } +} + +inline const char* FPRoundingModeToString(FPRoundingMode value) { + switch (value) { + case FPRoundingModeRTE: return "RTE"; + case FPRoundingModeRTZ: return "RTZ"; + case FPRoundingModeRTP: return "RTP"; + case FPRoundingModeRTN: return "RTN"; + default: return "Unknown"; + } +} + +inline const char* LinkageTypeToString(LinkageType value) { + switch (value) { + case LinkageTypeExport: return "Export"; + case LinkageTypeImport: return "Import"; + case LinkageTypeLinkOnceODR: return "LinkOnceODR"; + default: return "Unknown"; + } +} + +inline const char* AccessQualifierToString(AccessQualifier value) { + switch (value) { + case AccessQualifierReadOnly: return "ReadOnly"; + case AccessQualifierWriteOnly: return "WriteOnly"; + case AccessQualifierReadWrite: return "ReadWrite"; + default: return "Unknown"; + } +} + +inline const char* FunctionParameterAttributeToString(FunctionParameterAttribute value) { + switch (value) { + case FunctionParameterAttributeZext: return "Zext"; + case FunctionParameterAttributeSext: return "Sext"; + case FunctionParameterAttributeByVal: return "ByVal"; + case FunctionParameterAttributeSret: return "Sret"; + case FunctionParameterAttributeNoAlias: return "NoAlias"; + case FunctionParameterAttributeNoCapture: return "NoCapture"; + case FunctionParameterAttributeNoWrite: return "NoWrite"; + case FunctionParameterAttributeNoReadWrite: return "NoReadWrite"; + case FunctionParameterAttributeRuntimeAlignedINTEL: return "RuntimeAlignedINTEL"; + default: return "Unknown"; + } +} + +inline const char* DecorationToString(Decoration value) { + switch (value) { + case DecorationRelaxedPrecision: return "RelaxedPrecision"; + case DecorationSpecId: return "SpecId"; + case DecorationBlock: return "Block"; + case DecorationBufferBlock: return "BufferBlock"; + case DecorationRowMajor: return "RowMajor"; + case DecorationColMajor: return "ColMajor"; + case DecorationArrayStride: return "ArrayStride"; + case DecorationMatrixStride: return "MatrixStride"; + case DecorationGLSLShared: return "GLSLShared"; + case DecorationGLSLPacked: return "GLSLPacked"; + case DecorationCPacked: return "CPacked"; + case DecorationBuiltIn: return "BuiltIn"; + case DecorationNoPerspective: return "NoPerspective"; + case DecorationFlat: return "Flat"; + case DecorationPatch: return "Patch"; + case DecorationCentroid: return "Centroid"; + case DecorationSample: return "Sample"; + case DecorationInvariant: return "Invariant"; + case DecorationRestrict: return "Restrict"; + case DecorationAliased: return "Aliased"; + case DecorationVolatile: return "Volatile"; + case DecorationConstant: return "Constant"; + case DecorationCoherent: return "Coherent"; + case DecorationNonWritable: return "NonWritable"; + case DecorationNonReadable: return "NonReadable"; + case DecorationUniform: return "Uniform"; + case DecorationUniformId: return "UniformId"; + case DecorationSaturatedConversion: return "SaturatedConversion"; + case DecorationStream: return "Stream"; + case DecorationLocation: return "Location"; + case DecorationComponent: return "Component"; + case DecorationIndex: return "Index"; + case DecorationBinding: return "Binding"; + case DecorationDescriptorSet: return "DescriptorSet"; + case DecorationOffset: return "Offset"; + case DecorationXfbBuffer: return "XfbBuffer"; + case DecorationXfbStride: return "XfbStride"; + case DecorationFuncParamAttr: return "FuncParamAttr"; + case DecorationFPRoundingMode: return "FPRoundingMode"; + case DecorationFPFastMathMode: return "FPFastMathMode"; + case DecorationLinkageAttributes: return "LinkageAttributes"; + case DecorationNoContraction: return "NoContraction"; + case DecorationInputAttachmentIndex: return "InputAttachmentIndex"; + case DecorationAlignment: return "Alignment"; + case DecorationMaxByteOffset: return "MaxByteOffset"; + case DecorationAlignmentId: return "AlignmentId"; + case DecorationMaxByteOffsetId: return "MaxByteOffsetId"; + case DecorationNoSignedWrap: return "NoSignedWrap"; + case DecorationNoUnsignedWrap: return "NoUnsignedWrap"; + case DecorationWeightTextureQCOM: return "WeightTextureQCOM"; + case DecorationBlockMatchTextureQCOM: return "BlockMatchTextureQCOM"; + case DecorationBlockMatchSamplerQCOM: return "BlockMatchSamplerQCOM"; + case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case DecorationNodeSharesPayloadLimitsWithAMDX: return "NodeSharesPayloadLimitsWithAMDX"; + case DecorationNodeMaxPayloadsAMDX: return "NodeMaxPayloadsAMDX"; + case DecorationTrackFinishWritingAMDX: return "TrackFinishWritingAMDX"; + case DecorationPayloadNodeNameAMDX: return "PayloadNodeNameAMDX"; + case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; + case DecorationPassthroughNV: return "PassthroughNV"; + case DecorationViewportRelativeNV: return "ViewportRelativeNV"; + case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV"; + case DecorationPerPrimitiveEXT: return "PerPrimitiveEXT"; + case DecorationPerViewNV: return "PerViewNV"; + case DecorationPerTaskNV: return "PerTaskNV"; + case DecorationPerVertexKHR: return "PerVertexKHR"; + case DecorationNonUniform: return "NonUniform"; + case DecorationRestrictPointer: return "RestrictPointer"; + case DecorationAliasedPointer: return "AliasedPointer"; + case DecorationHitObjectShaderRecordBufferNV: return "HitObjectShaderRecordBufferNV"; + case DecorationBindlessSamplerNV: return "BindlessSamplerNV"; + case DecorationBindlessImageNV: return "BindlessImageNV"; + case DecorationBoundSamplerNV: return "BoundSamplerNV"; + case DecorationBoundImageNV: return "BoundImageNV"; + case DecorationSIMTCallINTEL: return "SIMTCallINTEL"; + case DecorationReferencedIndirectlyINTEL: return "ReferencedIndirectlyINTEL"; + case DecorationClobberINTEL: return "ClobberINTEL"; + case DecorationSideEffectsINTEL: return "SideEffectsINTEL"; + case DecorationVectorComputeVariableINTEL: return "VectorComputeVariableINTEL"; + case DecorationFuncParamIOKindINTEL: return "FuncParamIOKindINTEL"; + case DecorationVectorComputeFunctionINTEL: return "VectorComputeFunctionINTEL"; + case DecorationStackCallINTEL: return "StackCallINTEL"; + case DecorationGlobalVariableOffsetINTEL: return "GlobalVariableOffsetINTEL"; + case DecorationCounterBuffer: return "CounterBuffer"; + case DecorationHlslSemanticGOOGLE: return "HlslSemanticGOOGLE"; + case DecorationUserTypeGOOGLE: return "UserTypeGOOGLE"; + case DecorationFunctionRoundingModeINTEL: return "FunctionRoundingModeINTEL"; + case DecorationFunctionDenormModeINTEL: return "FunctionDenormModeINTEL"; + case DecorationRegisterINTEL: return "RegisterINTEL"; + case DecorationMemoryINTEL: return "MemoryINTEL"; + case DecorationNumbanksINTEL: return "NumbanksINTEL"; + case DecorationBankwidthINTEL: return "BankwidthINTEL"; + case DecorationMaxPrivateCopiesINTEL: return "MaxPrivateCopiesINTEL"; + case DecorationSinglepumpINTEL: return "SinglepumpINTEL"; + case DecorationDoublepumpINTEL: return "DoublepumpINTEL"; + case DecorationMaxReplicatesINTEL: return "MaxReplicatesINTEL"; + case DecorationSimpleDualPortINTEL: return "SimpleDualPortINTEL"; + case DecorationMergeINTEL: return "MergeINTEL"; + case DecorationBankBitsINTEL: return "BankBitsINTEL"; + case DecorationForcePow2DepthINTEL: return "ForcePow2DepthINTEL"; + case DecorationStridesizeINTEL: return "StridesizeINTEL"; + case DecorationWordsizeINTEL: return "WordsizeINTEL"; + case DecorationTrueDualPortINTEL: return "TrueDualPortINTEL"; + case DecorationBurstCoalesceINTEL: return "BurstCoalesceINTEL"; + case DecorationCacheSizeINTEL: return "CacheSizeINTEL"; + case DecorationDontStaticallyCoalesceINTEL: return "DontStaticallyCoalesceINTEL"; + case DecorationPrefetchINTEL: return "PrefetchINTEL"; + case DecorationStallEnableINTEL: return "StallEnableINTEL"; + case DecorationFuseLoopsInFunctionINTEL: return "FuseLoopsInFunctionINTEL"; + case DecorationMathOpDSPModeINTEL: return "MathOpDSPModeINTEL"; + case DecorationAliasScopeINTEL: return "AliasScopeINTEL"; + case DecorationNoAliasINTEL: return "NoAliasINTEL"; + case DecorationInitiationIntervalINTEL: return "InitiationIntervalINTEL"; + case DecorationMaxConcurrencyINTEL: return "MaxConcurrencyINTEL"; + case DecorationPipelineEnableINTEL: return "PipelineEnableINTEL"; + case DecorationBufferLocationINTEL: return "BufferLocationINTEL"; + case DecorationIOPipeStorageINTEL: return "IOPipeStorageINTEL"; + case DecorationFunctionFloatingPointModeINTEL: return "FunctionFloatingPointModeINTEL"; + case DecorationSingleElementVectorINTEL: return "SingleElementVectorINTEL"; + case DecorationVectorComputeCallableFunctionINTEL: return "VectorComputeCallableFunctionINTEL"; + case DecorationMediaBlockIOINTEL: return "MediaBlockIOINTEL"; + case DecorationStallFreeINTEL: return "StallFreeINTEL"; + case DecorationFPMaxErrorDecorationINTEL: return "FPMaxErrorDecorationINTEL"; + case DecorationLatencyControlLabelINTEL: return "LatencyControlLabelINTEL"; + case DecorationLatencyControlConstraintINTEL: return "LatencyControlConstraintINTEL"; + case DecorationConduitKernelArgumentINTEL: return "ConduitKernelArgumentINTEL"; + case DecorationRegisterMapKernelArgumentINTEL: return "RegisterMapKernelArgumentINTEL"; + case DecorationMMHostInterfaceAddressWidthINTEL: return "MMHostInterfaceAddressWidthINTEL"; + case DecorationMMHostInterfaceDataWidthINTEL: return "MMHostInterfaceDataWidthINTEL"; + case DecorationMMHostInterfaceLatencyINTEL: return "MMHostInterfaceLatencyINTEL"; + case DecorationMMHostInterfaceReadWriteModeINTEL: return "MMHostInterfaceReadWriteModeINTEL"; + case DecorationMMHostInterfaceMaxBurstINTEL: return "MMHostInterfaceMaxBurstINTEL"; + case DecorationMMHostInterfaceWaitRequestINTEL: return "MMHostInterfaceWaitRequestINTEL"; + case DecorationStableKernelArgumentINTEL: return "StableKernelArgumentINTEL"; + case DecorationHostAccessINTEL: return "HostAccessINTEL"; + case DecorationInitModeINTEL: return "InitModeINTEL"; + case DecorationImplementInRegisterMapINTEL: return "ImplementInRegisterMapINTEL"; + case DecorationCacheControlLoadINTEL: return "CacheControlLoadINTEL"; + case DecorationCacheControlStoreINTEL: return "CacheControlStoreINTEL"; + default: return "Unknown"; + } +} + +inline const char* BuiltInToString(BuiltIn value) { + switch (value) { + case BuiltInPosition: return "Position"; + case BuiltInPointSize: return "PointSize"; + case BuiltInClipDistance: return "ClipDistance"; + case BuiltInCullDistance: return "CullDistance"; + case BuiltInVertexId: return "VertexId"; + case BuiltInInstanceId: return "InstanceId"; + case BuiltInPrimitiveId: return "PrimitiveId"; + case BuiltInInvocationId: return "InvocationId"; + case BuiltInLayer: return "Layer"; + case BuiltInViewportIndex: return "ViewportIndex"; + case BuiltInTessLevelOuter: return "TessLevelOuter"; + case BuiltInTessLevelInner: return "TessLevelInner"; + case BuiltInTessCoord: return "TessCoord"; + case BuiltInPatchVertices: return "PatchVertices"; + case BuiltInFragCoord: return "FragCoord"; + case BuiltInPointCoord: return "PointCoord"; + case BuiltInFrontFacing: return "FrontFacing"; + case BuiltInSampleId: return "SampleId"; + case BuiltInSamplePosition: return "SamplePosition"; + case BuiltInSampleMask: return "SampleMask"; + case BuiltInFragDepth: return "FragDepth"; + case BuiltInHelperInvocation: return "HelperInvocation"; + case BuiltInNumWorkgroups: return "NumWorkgroups"; + case BuiltInWorkgroupSize: return "WorkgroupSize"; + case BuiltInWorkgroupId: return "WorkgroupId"; + case BuiltInLocalInvocationId: return "LocalInvocationId"; + case BuiltInGlobalInvocationId: return "GlobalInvocationId"; + case BuiltInLocalInvocationIndex: return "LocalInvocationIndex"; + case BuiltInWorkDim: return "WorkDim"; + case BuiltInGlobalSize: return "GlobalSize"; + case BuiltInEnqueuedWorkgroupSize: return "EnqueuedWorkgroupSize"; + case BuiltInGlobalOffset: return "GlobalOffset"; + case BuiltInGlobalLinearId: return "GlobalLinearId"; + case BuiltInSubgroupSize: return "SubgroupSize"; + case BuiltInSubgroupMaxSize: return "SubgroupMaxSize"; + case BuiltInNumSubgroups: return "NumSubgroups"; + case BuiltInNumEnqueuedSubgroups: return "NumEnqueuedSubgroups"; + case BuiltInSubgroupId: return "SubgroupId"; + case BuiltInSubgroupLocalInvocationId: return "SubgroupLocalInvocationId"; + case BuiltInVertexIndex: return "VertexIndex"; + case BuiltInInstanceIndex: return "InstanceIndex"; + case BuiltInCoreIDARM: return "CoreIDARM"; + case BuiltInCoreCountARM: return "CoreCountARM"; + case BuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case BuiltInWarpIDARM: return "WarpIDARM"; + case BuiltInWarpMaxIDARM: return "WarpMaxIDARM"; + case BuiltInSubgroupEqMask: return "SubgroupEqMask"; + case BuiltInSubgroupGeMask: return "SubgroupGeMask"; + case BuiltInSubgroupGtMask: return "SubgroupGtMask"; + case BuiltInSubgroupLeMask: return "SubgroupLeMask"; + case BuiltInSubgroupLtMask: return "SubgroupLtMask"; + case BuiltInBaseVertex: return "BaseVertex"; + case BuiltInBaseInstance: return "BaseInstance"; + case BuiltInDrawIndex: return "DrawIndex"; + case BuiltInPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case BuiltInDeviceIndex: return "DeviceIndex"; + case BuiltInViewIndex: return "ViewIndex"; + case BuiltInShadingRateKHR: return "ShadingRateKHR"; + case BuiltInBaryCoordNoPerspAMD: return "BaryCoordNoPerspAMD"; + case BuiltInBaryCoordNoPerspCentroidAMD: return "BaryCoordNoPerspCentroidAMD"; + case BuiltInBaryCoordNoPerspSampleAMD: return "BaryCoordNoPerspSampleAMD"; + case BuiltInBaryCoordSmoothAMD: return "BaryCoordSmoothAMD"; + case BuiltInBaryCoordSmoothCentroidAMD: return "BaryCoordSmoothCentroidAMD"; + case BuiltInBaryCoordSmoothSampleAMD: return "BaryCoordSmoothSampleAMD"; + case BuiltInBaryCoordPullModelAMD: return "BaryCoordPullModelAMD"; + case BuiltInFragStencilRefEXT: return "FragStencilRefEXT"; + case BuiltInCoalescedInputCountAMDX: return "CoalescedInputCountAMDX"; + case BuiltInShaderIndexAMDX: return "ShaderIndexAMDX"; + case BuiltInViewportMaskNV: return "ViewportMaskNV"; + case BuiltInSecondaryPositionNV: return "SecondaryPositionNV"; + case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV"; + case BuiltInPositionPerViewNV: return "PositionPerViewNV"; + case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; + case BuiltInFullyCoveredEXT: return "FullyCoveredEXT"; + case BuiltInTaskCountNV: return "TaskCountNV"; + case BuiltInPrimitiveCountNV: return "PrimitiveCountNV"; + case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV"; + case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV"; + case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV"; + case BuiltInLayerPerViewNV: return "LayerPerViewNV"; + case BuiltInMeshViewCountNV: return "MeshViewCountNV"; + case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV"; + case BuiltInBaryCoordKHR: return "BaryCoordKHR"; + case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; + case BuiltInFragSizeEXT: return "FragSizeEXT"; + case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; + case BuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case BuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case BuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case BuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case BuiltInLaunchIdKHR: return "LaunchIdKHR"; + case BuiltInLaunchSizeKHR: return "LaunchSizeKHR"; + case BuiltInWorldRayOriginKHR: return "WorldRayOriginKHR"; + case BuiltInWorldRayDirectionKHR: return "WorldRayDirectionKHR"; + case BuiltInObjectRayOriginKHR: return "ObjectRayOriginKHR"; + case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; + case BuiltInRayTminKHR: return "RayTminKHR"; + case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; + case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; + case BuiltInWorldToObjectKHR: return "WorldToObjectKHR"; + case BuiltInHitTNV: return "HitTNV"; + case BuiltInHitKindKHR: return "HitKindKHR"; + case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case BuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case BuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case BuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case BuiltInIncomingRayFlagsKHR: return "IncomingRayFlagsKHR"; + case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; + case BuiltInWarpsPerSMNV: return "WarpsPerSMNV"; + case BuiltInSMCountNV: return "SMCountNV"; + case BuiltInWarpIDNV: return "WarpIDNV"; + case BuiltInSMIDNV: return "SMIDNV"; + case BuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case BuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + case BuiltInCullMaskKHR: return "CullMaskKHR"; + default: return "Unknown"; + } +} + +inline const char* ScopeToString(Scope value) { + switch (value) { + case ScopeCrossDevice: return "CrossDevice"; + case ScopeDevice: return "Device"; + case ScopeWorkgroup: return "Workgroup"; + case ScopeSubgroup: return "Subgroup"; + case ScopeInvocation: return "Invocation"; + case ScopeQueueFamily: return "QueueFamily"; + case ScopeShaderCallKHR: return "ShaderCallKHR"; + default: return "Unknown"; + } +} + +inline const char* GroupOperationToString(GroupOperation value) { + switch (value) { + case GroupOperationReduce: return "Reduce"; + case GroupOperationInclusiveScan: return "InclusiveScan"; + case GroupOperationExclusiveScan: return "ExclusiveScan"; + case GroupOperationClusteredReduce: return "ClusteredReduce"; + case GroupOperationPartitionedReduceNV: return "PartitionedReduceNV"; + case GroupOperationPartitionedInclusiveScanNV: return "PartitionedInclusiveScanNV"; + case GroupOperationPartitionedExclusiveScanNV: return "PartitionedExclusiveScanNV"; + default: return "Unknown"; + } +} + +inline const char* KernelEnqueueFlagsToString(KernelEnqueueFlags value) { + switch (value) { + case KernelEnqueueFlagsNoWait: return "NoWait"; + case KernelEnqueueFlagsWaitKernel: return "WaitKernel"; + case KernelEnqueueFlagsWaitWorkGroup: return "WaitWorkGroup"; + default: return "Unknown"; + } +} + +inline const char* CapabilityToString(Capability value) { + switch (value) { + case CapabilityMatrix: return "Matrix"; + case CapabilityShader: return "Shader"; + case CapabilityGeometry: return "Geometry"; + case CapabilityTessellation: return "Tessellation"; + case CapabilityAddresses: return "Addresses"; + case CapabilityLinkage: return "Linkage"; + case CapabilityKernel: return "Kernel"; + case CapabilityVector16: return "Vector16"; + case CapabilityFloat16Buffer: return "Float16Buffer"; + case CapabilityFloat16: return "Float16"; + case CapabilityFloat64: return "Float64"; + case CapabilityInt64: return "Int64"; + case CapabilityInt64Atomics: return "Int64Atomics"; + case CapabilityImageBasic: return "ImageBasic"; + case CapabilityImageReadWrite: return "ImageReadWrite"; + case CapabilityImageMipmap: return "ImageMipmap"; + case CapabilityPipes: return "Pipes"; + case CapabilityGroups: return "Groups"; + case CapabilityDeviceEnqueue: return "DeviceEnqueue"; + case CapabilityLiteralSampler: return "LiteralSampler"; + case CapabilityAtomicStorage: return "AtomicStorage"; + case CapabilityInt16: return "Int16"; + case CapabilityTessellationPointSize: return "TessellationPointSize"; + case CapabilityGeometryPointSize: return "GeometryPointSize"; + case CapabilityImageGatherExtended: return "ImageGatherExtended"; + case CapabilityStorageImageMultisample: return "StorageImageMultisample"; + case CapabilityUniformBufferArrayDynamicIndexing: return "UniformBufferArrayDynamicIndexing"; + case CapabilitySampledImageArrayDynamicIndexing: return "SampledImageArrayDynamicIndexing"; + case CapabilityStorageBufferArrayDynamicIndexing: return "StorageBufferArrayDynamicIndexing"; + case CapabilityStorageImageArrayDynamicIndexing: return "StorageImageArrayDynamicIndexing"; + case CapabilityClipDistance: return "ClipDistance"; + case CapabilityCullDistance: return "CullDistance"; + case CapabilityImageCubeArray: return "ImageCubeArray"; + case CapabilitySampleRateShading: return "SampleRateShading"; + case CapabilityImageRect: return "ImageRect"; + case CapabilitySampledRect: return "SampledRect"; + case CapabilityGenericPointer: return "GenericPointer"; + case CapabilityInt8: return "Int8"; + case CapabilityInputAttachment: return "InputAttachment"; + case CapabilitySparseResidency: return "SparseResidency"; + case CapabilityMinLod: return "MinLod"; + case CapabilitySampled1D: return "Sampled1D"; + case CapabilityImage1D: return "Image1D"; + case CapabilitySampledCubeArray: return "SampledCubeArray"; + case CapabilitySampledBuffer: return "SampledBuffer"; + case CapabilityImageBuffer: return "ImageBuffer"; + case CapabilityImageMSArray: return "ImageMSArray"; + case CapabilityStorageImageExtendedFormats: return "StorageImageExtendedFormats"; + case CapabilityImageQuery: return "ImageQuery"; + case CapabilityDerivativeControl: return "DerivativeControl"; + case CapabilityInterpolationFunction: return "InterpolationFunction"; + case CapabilityTransformFeedback: return "TransformFeedback"; + case CapabilityGeometryStreams: return "GeometryStreams"; + case CapabilityStorageImageReadWithoutFormat: return "StorageImageReadWithoutFormat"; + case CapabilityStorageImageWriteWithoutFormat: return "StorageImageWriteWithoutFormat"; + case CapabilityMultiViewport: return "MultiViewport"; + case CapabilitySubgroupDispatch: return "SubgroupDispatch"; + case CapabilityNamedBarrier: return "NamedBarrier"; + case CapabilityPipeStorage: return "PipeStorage"; + case CapabilityGroupNonUniform: return "GroupNonUniform"; + case CapabilityGroupNonUniformVote: return "GroupNonUniformVote"; + case CapabilityGroupNonUniformArithmetic: return "GroupNonUniformArithmetic"; + case CapabilityGroupNonUniformBallot: return "GroupNonUniformBallot"; + case CapabilityGroupNonUniformShuffle: return "GroupNonUniformShuffle"; + case CapabilityGroupNonUniformShuffleRelative: return "GroupNonUniformShuffleRelative"; + case CapabilityGroupNonUniformClustered: return "GroupNonUniformClustered"; + case CapabilityGroupNonUniformQuad: return "GroupNonUniformQuad"; + case CapabilityShaderLayer: return "ShaderLayer"; + case CapabilityShaderViewportIndex: return "ShaderViewportIndex"; + case CapabilityUniformDecoration: return "UniformDecoration"; + case CapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + case CapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case CapabilityCooperativeMatrixLayoutsARM: return "CooperativeMatrixLayoutsARM"; + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; + case CapabilitySubgroupBallotKHR: return "SubgroupBallotKHR"; + case CapabilityDrawParameters: return "DrawParameters"; + case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "WorkgroupMemoryExplicitLayoutKHR"; + case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "WorkgroupMemoryExplicitLayout8BitAccessKHR"; + case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "WorkgroupMemoryExplicitLayout16BitAccessKHR"; + case CapabilitySubgroupVoteKHR: return "SubgroupVoteKHR"; + case CapabilityStorageBuffer16BitAccess: return "StorageBuffer16BitAccess"; + case CapabilityStorageUniform16: return "StorageUniform16"; + case CapabilityStoragePushConstant16: return "StoragePushConstant16"; + case CapabilityStorageInputOutput16: return "StorageInputOutput16"; + case CapabilityDeviceGroup: return "DeviceGroup"; + case CapabilityMultiView: return "MultiView"; + case CapabilityVariablePointersStorageBuffer: return "VariablePointersStorageBuffer"; + case CapabilityVariablePointers: return "VariablePointers"; + case CapabilityAtomicStorageOps: return "AtomicStorageOps"; + case CapabilitySampleMaskPostDepthCoverage: return "SampleMaskPostDepthCoverage"; + case CapabilityStorageBuffer8BitAccess: return "StorageBuffer8BitAccess"; + case CapabilityUniformAndStorageBuffer8BitAccess: return "UniformAndStorageBuffer8BitAccess"; + case CapabilityStoragePushConstant8: return "StoragePushConstant8"; + case CapabilityDenormPreserve: return "DenormPreserve"; + case CapabilityDenormFlushToZero: return "DenormFlushToZero"; + case CapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case CapabilityRoundingModeRTE: return "RoundingModeRTE"; + case CapabilityRoundingModeRTZ: return "RoundingModeRTZ"; + case CapabilityRayQueryProvisionalKHR: return "RayQueryProvisionalKHR"; + case CapabilityRayQueryKHR: return "RayQueryKHR"; + case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case CapabilityRayTracingKHR: return "RayTracingKHR"; + case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; + case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; + case CapabilityFloat16ImageAMD: return "Float16ImageAMD"; + case CapabilityImageGatherBiasLodAMD: return "ImageGatherBiasLodAMD"; + case CapabilityFragmentMaskAMD: return "FragmentMaskAMD"; + case CapabilityStencilExportEXT: return "StencilExportEXT"; + case CapabilityImageReadWriteLodAMD: return "ImageReadWriteLodAMD"; + case CapabilityInt64ImageEXT: return "Int64ImageEXT"; + case CapabilityShaderClockKHR: return "ShaderClockKHR"; + case CapabilityShaderEnqueueAMDX: return "ShaderEnqueueAMDX"; + case CapabilityQuadControlKHR: return "QuadControlKHR"; + case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; + case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV"; + case CapabilityShaderViewportIndexLayerEXT: return "ShaderViewportIndexLayerEXT"; + case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV"; + case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV"; + case CapabilityPerViewAttributesNV: return "PerViewAttributesNV"; + case CapabilityFragmentFullyCoveredEXT: return "FragmentFullyCoveredEXT"; + case CapabilityMeshShadingNV: return "MeshShadingNV"; + case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilityMeshShadingEXT: return "MeshShadingEXT"; + case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; + case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; + case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; + case CapabilityGroupNonUniformPartitionedNV: return "GroupNonUniformPartitionedNV"; + case CapabilityShaderNonUniform: return "ShaderNonUniform"; + case CapabilityRuntimeDescriptorArray: return "RuntimeDescriptorArray"; + case CapabilityInputAttachmentArrayDynamicIndexing: return "InputAttachmentArrayDynamicIndexing"; + case CapabilityUniformTexelBufferArrayDynamicIndexing: return "UniformTexelBufferArrayDynamicIndexing"; + case CapabilityStorageTexelBufferArrayDynamicIndexing: return "StorageTexelBufferArrayDynamicIndexing"; + case CapabilityUniformBufferArrayNonUniformIndexing: return "UniformBufferArrayNonUniformIndexing"; + case CapabilitySampledImageArrayNonUniformIndexing: return "SampledImageArrayNonUniformIndexing"; + case CapabilityStorageBufferArrayNonUniformIndexing: return "StorageBufferArrayNonUniformIndexing"; + case CapabilityStorageImageArrayNonUniformIndexing: return "StorageImageArrayNonUniformIndexing"; + case CapabilityInputAttachmentArrayNonUniformIndexing: return "InputAttachmentArrayNonUniformIndexing"; + case CapabilityUniformTexelBufferArrayNonUniformIndexing: return "UniformTexelBufferArrayNonUniformIndexing"; + case CapabilityStorageTexelBufferArrayNonUniformIndexing: return "StorageTexelBufferArrayNonUniformIndexing"; + case CapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case CapabilityRayTracingNV: return "RayTracingNV"; + case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; + case CapabilityVulkanMemoryModel: return "VulkanMemoryModel"; + case CapabilityVulkanMemoryModelDeviceScope: return "VulkanMemoryModelDeviceScope"; + case CapabilityPhysicalStorageBufferAddresses: return "PhysicalStorageBufferAddresses"; + case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; + case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; + case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityFragmentShaderSampleInterlockEXT: return "FragmentShaderSampleInterlockEXT"; + case CapabilityFragmentShaderShadingRateInterlockEXT: return "FragmentShaderShadingRateInterlockEXT"; + case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; + case CapabilityFragmentShaderPixelInterlockEXT: return "FragmentShaderPixelInterlockEXT"; + case CapabilityDemoteToHelperInvocation: return "DemoteToHelperInvocation"; + case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case CapabilityRayTracingOpacityMicromapEXT: return "RayTracingOpacityMicromapEXT"; + case CapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + case CapabilityBindlessTextureNV: return "BindlessTextureNV"; + case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; + case CapabilityAtomicFloat16VectorNV: return "AtomicFloat16VectorNV"; + case CapabilityRayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case CapabilityRawAccessChainsNV: return "RawAccessChainsNV"; + case CapabilitySubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; + case CapabilitySubgroupBufferBlockIOINTEL: return "SubgroupBufferBlockIOINTEL"; + case CapabilitySubgroupImageBlockIOINTEL: return "SubgroupImageBlockIOINTEL"; + case CapabilitySubgroupImageMediaBlockIOINTEL: return "SubgroupImageMediaBlockIOINTEL"; + case CapabilityRoundToInfinityINTEL: return "RoundToInfinityINTEL"; + case CapabilityFloatingPointModeINTEL: return "FloatingPointModeINTEL"; + case CapabilityIntegerFunctions2INTEL: return "IntegerFunctions2INTEL"; + case CapabilityFunctionPointersINTEL: return "FunctionPointersINTEL"; + case CapabilityIndirectReferencesINTEL: return "IndirectReferencesINTEL"; + case CapabilityAsmINTEL: return "AsmINTEL"; + case CapabilityAtomicFloat32MinMaxEXT: return "AtomicFloat32MinMaxEXT"; + case CapabilityAtomicFloat64MinMaxEXT: return "AtomicFloat64MinMaxEXT"; + case CapabilityAtomicFloat16MinMaxEXT: return "AtomicFloat16MinMaxEXT"; + case CapabilityVectorComputeINTEL: return "VectorComputeINTEL"; + case CapabilityVectorAnyINTEL: return "VectorAnyINTEL"; + case CapabilityExpectAssumeKHR: return "ExpectAssumeKHR"; + case CapabilitySubgroupAvcMotionEstimationINTEL: return "SubgroupAvcMotionEstimationINTEL"; + case CapabilitySubgroupAvcMotionEstimationIntraINTEL: return "SubgroupAvcMotionEstimationIntraINTEL"; + case CapabilitySubgroupAvcMotionEstimationChromaINTEL: return "SubgroupAvcMotionEstimationChromaINTEL"; + case CapabilityVariableLengthArrayINTEL: return "VariableLengthArrayINTEL"; + case CapabilityFunctionFloatControlINTEL: return "FunctionFloatControlINTEL"; + case CapabilityFPGAMemoryAttributesINTEL: return "FPGAMemoryAttributesINTEL"; + case CapabilityFPFastMathModeINTEL: return "FPFastMathModeINTEL"; + case CapabilityArbitraryPrecisionIntegersINTEL: return "ArbitraryPrecisionIntegersINTEL"; + case CapabilityArbitraryPrecisionFloatingPointINTEL: return "ArbitraryPrecisionFloatingPointINTEL"; + case CapabilityUnstructuredLoopControlsINTEL: return "UnstructuredLoopControlsINTEL"; + case CapabilityFPGALoopControlsINTEL: return "FPGALoopControlsINTEL"; + case CapabilityKernelAttributesINTEL: return "KernelAttributesINTEL"; + case CapabilityFPGAKernelAttributesINTEL: return "FPGAKernelAttributesINTEL"; + case CapabilityFPGAMemoryAccessesINTEL: return "FPGAMemoryAccessesINTEL"; + case CapabilityFPGAClusterAttributesINTEL: return "FPGAClusterAttributesINTEL"; + case CapabilityLoopFuseINTEL: return "LoopFuseINTEL"; + case CapabilityFPGADSPControlINTEL: return "FPGADSPControlINTEL"; + case CapabilityMemoryAccessAliasingINTEL: return "MemoryAccessAliasingINTEL"; + case CapabilityFPGAInvocationPipeliningAttributesINTEL: return "FPGAInvocationPipeliningAttributesINTEL"; + case CapabilityFPGABufferLocationINTEL: return "FPGABufferLocationINTEL"; + case CapabilityArbitraryPrecisionFixedPointINTEL: return "ArbitraryPrecisionFixedPointINTEL"; + case CapabilityUSMStorageClassesINTEL: return "USMStorageClassesINTEL"; + case CapabilityRuntimeAlignedAttributeINTEL: return "RuntimeAlignedAttributeINTEL"; + case CapabilityIOPipesINTEL: return "IOPipesINTEL"; + case CapabilityBlockingPipesINTEL: return "BlockingPipesINTEL"; + case CapabilityFPGARegINTEL: return "FPGARegINTEL"; + case CapabilityDotProductInputAll: return "DotProductInputAll"; + case CapabilityDotProductInput4x8Bit: return "DotProductInput4x8Bit"; + case CapabilityDotProductInput4x8BitPacked: return "DotProductInput4x8BitPacked"; + case CapabilityDotProduct: return "DotProduct"; + case CapabilityRayCullMaskKHR: return "RayCullMaskKHR"; + case CapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case CapabilityReplicatedCompositesEXT: return "ReplicatedCompositesEXT"; + case CapabilityBitInstructions: return "BitInstructions"; + case CapabilityGroupNonUniformRotateKHR: return "GroupNonUniformRotateKHR"; + case CapabilityFloatControls2: return "FloatControls2"; + case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT"; + case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT"; + case CapabilityLongCompositesINTEL: return "LongCompositesINTEL"; + case CapabilityOptNoneINTEL: return "OptNoneINTEL"; + case CapabilityAtomicFloat16AddEXT: return "AtomicFloat16AddEXT"; + case CapabilityDebugInfoModuleINTEL: return "DebugInfoModuleINTEL"; + case CapabilityBFloat16ConversionINTEL: return "BFloat16ConversionINTEL"; + case CapabilitySplitBarrierINTEL: return "SplitBarrierINTEL"; + case CapabilityFPGAClusterAttributesV2INTEL: return "FPGAClusterAttributesV2INTEL"; + case CapabilityFPGAKernelAttributesv2INTEL: return "FPGAKernelAttributesv2INTEL"; + case CapabilityFPMaxErrorINTEL: return "FPMaxErrorINTEL"; + case CapabilityFPGALatencyControlINTEL: return "FPGALatencyControlINTEL"; + case CapabilityFPGAArgumentInterfacesINTEL: return "FPGAArgumentInterfacesINTEL"; + case CapabilityGlobalVariableHostAccessINTEL: return "GlobalVariableHostAccessINTEL"; + case CapabilityGlobalVariableFPGADecorationsINTEL: return "GlobalVariableFPGADecorationsINTEL"; + case CapabilityGroupUniformArithmeticKHR: return "GroupUniformArithmeticKHR"; + case CapabilityMaskedGatherScatterINTEL: return "MaskedGatherScatterINTEL"; + case CapabilityCacheControlsINTEL: return "CacheControlsINTEL"; + case CapabilityRegisterLimitsINTEL: return "RegisterLimitsINTEL"; + default: return "Unknown"; + } +} + +inline const char* RayQueryIntersectionToString(RayQueryIntersection value) { + switch (value) { + case RayQueryIntersectionRayQueryCandidateIntersectionKHR: return "RayQueryCandidateIntersectionKHR"; + case RayQueryIntersectionRayQueryCommittedIntersectionKHR: return "RayQueryCommittedIntersectionKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCommittedIntersectionTypeToString(RayQueryCommittedIntersectionType value) { + switch (value) { + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR: return "RayQueryCommittedIntersectionNoneKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR: return "RayQueryCommittedIntersectionTriangleKHR"; + case RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR: return "RayQueryCommittedIntersectionGeneratedKHR"; + default: return "Unknown"; + } +} + +inline const char* RayQueryCandidateIntersectionTypeToString(RayQueryCandidateIntersectionType value) { + switch (value) { + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR: return "RayQueryCandidateIntersectionTriangleKHR"; + case RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR: return "RayQueryCandidateIntersectionAABBKHR"; + default: return "Unknown"; + } +} + +inline const char* FPDenormModeToString(FPDenormMode value) { + switch (value) { + case FPDenormModePreserve: return "Preserve"; + case FPDenormModeFlushToZero: return "FlushToZero"; + default: return "Unknown"; + } +} + +inline const char* FPOperationModeToString(FPOperationMode value) { + switch (value) { + case FPOperationModeIEEE: return "IEEE"; + case FPOperationModeALT: return "ALT"; + default: return "Unknown"; + } +} + +inline const char* QuantizationModesToString(QuantizationModes value) { + switch (value) { + case QuantizationModesTRN: return "TRN"; + case QuantizationModesTRN_ZERO: return "TRN_ZERO"; + case QuantizationModesRND: return "RND"; + case QuantizationModesRND_ZERO: return "RND_ZERO"; + case QuantizationModesRND_INF: return "RND_INF"; + case QuantizationModesRND_MIN_INF: return "RND_MIN_INF"; + case QuantizationModesRND_CONV: return "RND_CONV"; + case QuantizationModesRND_CONV_ODD: return "RND_CONV_ODD"; + default: return "Unknown"; + } +} + +inline const char* OverflowModesToString(OverflowModes value) { + switch (value) { + case OverflowModesWRAP: return "WRAP"; + case OverflowModesSAT: return "SAT"; + case OverflowModesSAT_ZERO: return "SAT_ZERO"; + case OverflowModesSAT_SYM: return "SAT_SYM"; + default: return "Unknown"; + } +} + +inline const char* PackedVectorFormatToString(PackedVectorFormat value) { + switch (value) { + case PackedVectorFormatPackedVectorFormat4x8Bit: return "PackedVectorFormat4x8Bit"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixLayoutToString(CooperativeMatrixLayout value) { + switch (value) { + case CooperativeMatrixLayoutRowMajorKHR: return "RowMajorKHR"; + case CooperativeMatrixLayoutColumnMajorKHR: return "ColumnMajorKHR"; + case CooperativeMatrixLayoutRowBlockedInterleavedARM: return "RowBlockedInterleavedARM"; + case CooperativeMatrixLayoutColumnBlockedInterleavedARM: return "ColumnBlockedInterleavedARM"; + default: return "Unknown"; + } +} + +inline const char* CooperativeMatrixUseToString(CooperativeMatrixUse value) { + switch (value) { + case CooperativeMatrixUseMatrixAKHR: return "MatrixAKHR"; + case CooperativeMatrixUseMatrixBKHR: return "MatrixBKHR"; + case CooperativeMatrixUseMatrixAccumulatorKHR: return "MatrixAccumulatorKHR"; + default: return "Unknown"; + } +} + +inline const char* InitializationModeQualifierToString(InitializationModeQualifier value) { + switch (value) { + case InitializationModeQualifierInitOnDeviceReprogramINTEL: return "InitOnDeviceReprogramINTEL"; + case InitializationModeQualifierInitOnDeviceResetINTEL: return "InitOnDeviceResetINTEL"; + default: return "Unknown"; + } +} + +inline const char* HostAccessQualifierToString(HostAccessQualifier value) { + switch (value) { + case HostAccessQualifierNoneINTEL: return "NoneINTEL"; + case HostAccessQualifierReadINTEL: return "ReadINTEL"; + case HostAccessQualifierWriteINTEL: return "WriteINTEL"; + case HostAccessQualifierReadWriteINTEL: return "ReadWriteINTEL"; + default: return "Unknown"; + } +} + +inline const char* LoadCacheControlToString(LoadCacheControl value) { + switch (value) { + case LoadCacheControlUncachedINTEL: return "UncachedINTEL"; + case LoadCacheControlCachedINTEL: return "CachedINTEL"; + case LoadCacheControlStreamingINTEL: return "StreamingINTEL"; + case LoadCacheControlInvalidateAfterReadINTEL: return "InvalidateAfterReadINTEL"; + case LoadCacheControlConstCachedINTEL: return "ConstCachedINTEL"; + default: return "Unknown"; + } +} + +inline const char* StoreCacheControlToString(StoreCacheControl value) { + switch (value) { + case StoreCacheControlUncachedINTEL: return "UncachedINTEL"; + case StoreCacheControlWriteThroughINTEL: return "WriteThroughINTEL"; + case StoreCacheControlWriteBackINTEL: return "WriteBackINTEL"; + case StoreCacheControlStreamingINTEL: return "StreamingINTEL"; + default: return "Unknown"; + } +} + +inline const char* NamedMaximumNumberOfRegistersToString(NamedMaximumNumberOfRegisters value) { + switch (value) { + case NamedMaximumNumberOfRegistersAutoINTEL: return "AutoINTEL"; + default: return "Unknown"; + } +} + +inline const char* OpToString(Op value) { + switch (value) { + case OpNop: return "OpNop"; + case OpUndef: return "OpUndef"; + case OpSourceContinued: return "OpSourceContinued"; + case OpSource: return "OpSource"; + case OpSourceExtension: return "OpSourceExtension"; + case OpName: return "OpName"; + case OpMemberName: return "OpMemberName"; + case OpString: return "OpString"; + case OpLine: return "OpLine"; + case OpExtension: return "OpExtension"; + case OpExtInstImport: return "OpExtInstImport"; + case OpExtInst: return "OpExtInst"; + case OpMemoryModel: return "OpMemoryModel"; + case OpEntryPoint: return "OpEntryPoint"; + case OpExecutionMode: return "OpExecutionMode"; + case OpCapability: return "OpCapability"; + case OpTypeVoid: return "OpTypeVoid"; + case OpTypeBool: return "OpTypeBool"; + case OpTypeInt: return "OpTypeInt"; + case OpTypeFloat: return "OpTypeFloat"; + case OpTypeVector: return "OpTypeVector"; + case OpTypeMatrix: return "OpTypeMatrix"; + case OpTypeImage: return "OpTypeImage"; + case OpTypeSampler: return "OpTypeSampler"; + case OpTypeSampledImage: return "OpTypeSampledImage"; + case OpTypeArray: return "OpTypeArray"; + case OpTypeRuntimeArray: return "OpTypeRuntimeArray"; + case OpTypeStruct: return "OpTypeStruct"; + case OpTypeOpaque: return "OpTypeOpaque"; + case OpTypePointer: return "OpTypePointer"; + case OpTypeFunction: return "OpTypeFunction"; + case OpTypeEvent: return "OpTypeEvent"; + case OpTypeDeviceEvent: return "OpTypeDeviceEvent"; + case OpTypeReserveId: return "OpTypeReserveId"; + case OpTypeQueue: return "OpTypeQueue"; + case OpTypePipe: return "OpTypePipe"; + case OpTypeForwardPointer: return "OpTypeForwardPointer"; + case OpConstantTrue: return "OpConstantTrue"; + case OpConstantFalse: return "OpConstantFalse"; + case OpConstant: return "OpConstant"; + case OpConstantComposite: return "OpConstantComposite"; + case OpConstantSampler: return "OpConstantSampler"; + case OpConstantNull: return "OpConstantNull"; + case OpSpecConstantTrue: return "OpSpecConstantTrue"; + case OpSpecConstantFalse: return "OpSpecConstantFalse"; + case OpSpecConstant: return "OpSpecConstant"; + case OpSpecConstantComposite: return "OpSpecConstantComposite"; + case OpSpecConstantOp: return "OpSpecConstantOp"; + case OpFunction: return "OpFunction"; + case OpFunctionParameter: return "OpFunctionParameter"; + case OpFunctionEnd: return "OpFunctionEnd"; + case OpFunctionCall: return "OpFunctionCall"; + case OpVariable: return "OpVariable"; + case OpImageTexelPointer: return "OpImageTexelPointer"; + case OpLoad: return "OpLoad"; + case OpStore: return "OpStore"; + case OpCopyMemory: return "OpCopyMemory"; + case OpCopyMemorySized: return "OpCopyMemorySized"; + case OpAccessChain: return "OpAccessChain"; + case OpInBoundsAccessChain: return "OpInBoundsAccessChain"; + case OpPtrAccessChain: return "OpPtrAccessChain"; + case OpArrayLength: return "OpArrayLength"; + case OpGenericPtrMemSemantics: return "OpGenericPtrMemSemantics"; + case OpInBoundsPtrAccessChain: return "OpInBoundsPtrAccessChain"; + case OpDecorate: return "OpDecorate"; + case OpMemberDecorate: return "OpMemberDecorate"; + case OpDecorationGroup: return "OpDecorationGroup"; + case OpGroupDecorate: return "OpGroupDecorate"; + case OpGroupMemberDecorate: return "OpGroupMemberDecorate"; + case OpVectorExtractDynamic: return "OpVectorExtractDynamic"; + case OpVectorInsertDynamic: return "OpVectorInsertDynamic"; + case OpVectorShuffle: return "OpVectorShuffle"; + case OpCompositeConstruct: return "OpCompositeConstruct"; + case OpCompositeExtract: return "OpCompositeExtract"; + case OpCompositeInsert: return "OpCompositeInsert"; + case OpCopyObject: return "OpCopyObject"; + case OpTranspose: return "OpTranspose"; + case OpSampledImage: return "OpSampledImage"; + case OpImageSampleImplicitLod: return "OpImageSampleImplicitLod"; + case OpImageSampleExplicitLod: return "OpImageSampleExplicitLod"; + case OpImageSampleDrefImplicitLod: return "OpImageSampleDrefImplicitLod"; + case OpImageSampleDrefExplicitLod: return "OpImageSampleDrefExplicitLod"; + case OpImageSampleProjImplicitLod: return "OpImageSampleProjImplicitLod"; + case OpImageSampleProjExplicitLod: return "OpImageSampleProjExplicitLod"; + case OpImageSampleProjDrefImplicitLod: return "OpImageSampleProjDrefImplicitLod"; + case OpImageSampleProjDrefExplicitLod: return "OpImageSampleProjDrefExplicitLod"; + case OpImageFetch: return "OpImageFetch"; + case OpImageGather: return "OpImageGather"; + case OpImageDrefGather: return "OpImageDrefGather"; + case OpImageRead: return "OpImageRead"; + case OpImageWrite: return "OpImageWrite"; + case OpImage: return "OpImage"; + case OpImageQueryFormat: return "OpImageQueryFormat"; + case OpImageQueryOrder: return "OpImageQueryOrder"; + case OpImageQuerySizeLod: return "OpImageQuerySizeLod"; + case OpImageQuerySize: return "OpImageQuerySize"; + case OpImageQueryLod: return "OpImageQueryLod"; + case OpImageQueryLevels: return "OpImageQueryLevels"; + case OpImageQuerySamples: return "OpImageQuerySamples"; + case OpConvertFToU: return "OpConvertFToU"; + case OpConvertFToS: return "OpConvertFToS"; + case OpConvertSToF: return "OpConvertSToF"; + case OpConvertUToF: return "OpConvertUToF"; + case OpUConvert: return "OpUConvert"; + case OpSConvert: return "OpSConvert"; + case OpFConvert: return "OpFConvert"; + case OpQuantizeToF16: return "OpQuantizeToF16"; + case OpConvertPtrToU: return "OpConvertPtrToU"; + case OpSatConvertSToU: return "OpSatConvertSToU"; + case OpSatConvertUToS: return "OpSatConvertUToS"; + case OpConvertUToPtr: return "OpConvertUToPtr"; + case OpPtrCastToGeneric: return "OpPtrCastToGeneric"; + case OpGenericCastToPtr: return "OpGenericCastToPtr"; + case OpGenericCastToPtrExplicit: return "OpGenericCastToPtrExplicit"; + case OpBitcast: return "OpBitcast"; + case OpSNegate: return "OpSNegate"; + case OpFNegate: return "OpFNegate"; + case OpIAdd: return "OpIAdd"; + case OpFAdd: return "OpFAdd"; + case OpISub: return "OpISub"; + case OpFSub: return "OpFSub"; + case OpIMul: return "OpIMul"; + case OpFMul: return "OpFMul"; + case OpUDiv: return "OpUDiv"; + case OpSDiv: return "OpSDiv"; + case OpFDiv: return "OpFDiv"; + case OpUMod: return "OpUMod"; + case OpSRem: return "OpSRem"; + case OpSMod: return "OpSMod"; + case OpFRem: return "OpFRem"; + case OpFMod: return "OpFMod"; + case OpVectorTimesScalar: return "OpVectorTimesScalar"; + case OpMatrixTimesScalar: return "OpMatrixTimesScalar"; + case OpVectorTimesMatrix: return "OpVectorTimesMatrix"; + case OpMatrixTimesVector: return "OpMatrixTimesVector"; + case OpMatrixTimesMatrix: return "OpMatrixTimesMatrix"; + case OpOuterProduct: return "OpOuterProduct"; + case OpDot: return "OpDot"; + case OpIAddCarry: return "OpIAddCarry"; + case OpISubBorrow: return "OpISubBorrow"; + case OpUMulExtended: return "OpUMulExtended"; + case OpSMulExtended: return "OpSMulExtended"; + case OpAny: return "OpAny"; + case OpAll: return "OpAll"; + case OpIsNan: return "OpIsNan"; + case OpIsInf: return "OpIsInf"; + case OpIsFinite: return "OpIsFinite"; + case OpIsNormal: return "OpIsNormal"; + case OpSignBitSet: return "OpSignBitSet"; + case OpLessOrGreater: return "OpLessOrGreater"; + case OpOrdered: return "OpOrdered"; + case OpUnordered: return "OpUnordered"; + case OpLogicalEqual: return "OpLogicalEqual"; + case OpLogicalNotEqual: return "OpLogicalNotEqual"; + case OpLogicalOr: return "OpLogicalOr"; + case OpLogicalAnd: return "OpLogicalAnd"; + case OpLogicalNot: return "OpLogicalNot"; + case OpSelect: return "OpSelect"; + case OpIEqual: return "OpIEqual"; + case OpINotEqual: return "OpINotEqual"; + case OpUGreaterThan: return "OpUGreaterThan"; + case OpSGreaterThan: return "OpSGreaterThan"; + case OpUGreaterThanEqual: return "OpUGreaterThanEqual"; + case OpSGreaterThanEqual: return "OpSGreaterThanEqual"; + case OpULessThan: return "OpULessThan"; + case OpSLessThan: return "OpSLessThan"; + case OpULessThanEqual: return "OpULessThanEqual"; + case OpSLessThanEqual: return "OpSLessThanEqual"; + case OpFOrdEqual: return "OpFOrdEqual"; + case OpFUnordEqual: return "OpFUnordEqual"; + case OpFOrdNotEqual: return "OpFOrdNotEqual"; + case OpFUnordNotEqual: return "OpFUnordNotEqual"; + case OpFOrdLessThan: return "OpFOrdLessThan"; + case OpFUnordLessThan: return "OpFUnordLessThan"; + case OpFOrdGreaterThan: return "OpFOrdGreaterThan"; + case OpFUnordGreaterThan: return "OpFUnordGreaterThan"; + case OpFOrdLessThanEqual: return "OpFOrdLessThanEqual"; + case OpFUnordLessThanEqual: return "OpFUnordLessThanEqual"; + case OpFOrdGreaterThanEqual: return "OpFOrdGreaterThanEqual"; + case OpFUnordGreaterThanEqual: return "OpFUnordGreaterThanEqual"; + case OpShiftRightLogical: return "OpShiftRightLogical"; + case OpShiftRightArithmetic: return "OpShiftRightArithmetic"; + case OpShiftLeftLogical: return "OpShiftLeftLogical"; + case OpBitwiseOr: return "OpBitwiseOr"; + case OpBitwiseXor: return "OpBitwiseXor"; + case OpBitwiseAnd: return "OpBitwiseAnd"; + case OpNot: return "OpNot"; + case OpBitFieldInsert: return "OpBitFieldInsert"; + case OpBitFieldSExtract: return "OpBitFieldSExtract"; + case OpBitFieldUExtract: return "OpBitFieldUExtract"; + case OpBitReverse: return "OpBitReverse"; + case OpBitCount: return "OpBitCount"; + case OpDPdx: return "OpDPdx"; + case OpDPdy: return "OpDPdy"; + case OpFwidth: return "OpFwidth"; + case OpDPdxFine: return "OpDPdxFine"; + case OpDPdyFine: return "OpDPdyFine"; + case OpFwidthFine: return "OpFwidthFine"; + case OpDPdxCoarse: return "OpDPdxCoarse"; + case OpDPdyCoarse: return "OpDPdyCoarse"; + case OpFwidthCoarse: return "OpFwidthCoarse"; + case OpEmitVertex: return "OpEmitVertex"; + case OpEndPrimitive: return "OpEndPrimitive"; + case OpEmitStreamVertex: return "OpEmitStreamVertex"; + case OpEndStreamPrimitive: return "OpEndStreamPrimitive"; + case OpControlBarrier: return "OpControlBarrier"; + case OpMemoryBarrier: return "OpMemoryBarrier"; + case OpAtomicLoad: return "OpAtomicLoad"; + case OpAtomicStore: return "OpAtomicStore"; + case OpAtomicExchange: return "OpAtomicExchange"; + case OpAtomicCompareExchange: return "OpAtomicCompareExchange"; + case OpAtomicCompareExchangeWeak: return "OpAtomicCompareExchangeWeak"; + case OpAtomicIIncrement: return "OpAtomicIIncrement"; + case OpAtomicIDecrement: return "OpAtomicIDecrement"; + case OpAtomicIAdd: return "OpAtomicIAdd"; + case OpAtomicISub: return "OpAtomicISub"; + case OpAtomicSMin: return "OpAtomicSMin"; + case OpAtomicUMin: return "OpAtomicUMin"; + case OpAtomicSMax: return "OpAtomicSMax"; + case OpAtomicUMax: return "OpAtomicUMax"; + case OpAtomicAnd: return "OpAtomicAnd"; + case OpAtomicOr: return "OpAtomicOr"; + case OpAtomicXor: return "OpAtomicXor"; + case OpPhi: return "OpPhi"; + case OpLoopMerge: return "OpLoopMerge"; + case OpSelectionMerge: return "OpSelectionMerge"; + case OpLabel: return "OpLabel"; + case OpBranch: return "OpBranch"; + case OpBranchConditional: return "OpBranchConditional"; + case OpSwitch: return "OpSwitch"; + case OpKill: return "OpKill"; + case OpReturn: return "OpReturn"; + case OpReturnValue: return "OpReturnValue"; + case OpUnreachable: return "OpUnreachable"; + case OpLifetimeStart: return "OpLifetimeStart"; + case OpLifetimeStop: return "OpLifetimeStop"; + case OpGroupAsyncCopy: return "OpGroupAsyncCopy"; + case OpGroupWaitEvents: return "OpGroupWaitEvents"; + case OpGroupAll: return "OpGroupAll"; + case OpGroupAny: return "OpGroupAny"; + case OpGroupBroadcast: return "OpGroupBroadcast"; + case OpGroupIAdd: return "OpGroupIAdd"; + case OpGroupFAdd: return "OpGroupFAdd"; + case OpGroupFMin: return "OpGroupFMin"; + case OpGroupUMin: return "OpGroupUMin"; + case OpGroupSMin: return "OpGroupSMin"; + case OpGroupFMax: return "OpGroupFMax"; + case OpGroupUMax: return "OpGroupUMax"; + case OpGroupSMax: return "OpGroupSMax"; + case OpReadPipe: return "OpReadPipe"; + case OpWritePipe: return "OpWritePipe"; + case OpReservedReadPipe: return "OpReservedReadPipe"; + case OpReservedWritePipe: return "OpReservedWritePipe"; + case OpReserveReadPipePackets: return "OpReserveReadPipePackets"; + case OpReserveWritePipePackets: return "OpReserveWritePipePackets"; + case OpCommitReadPipe: return "OpCommitReadPipe"; + case OpCommitWritePipe: return "OpCommitWritePipe"; + case OpIsValidReserveId: return "OpIsValidReserveId"; + case OpGetNumPipePackets: return "OpGetNumPipePackets"; + case OpGetMaxPipePackets: return "OpGetMaxPipePackets"; + case OpGroupReserveReadPipePackets: return "OpGroupReserveReadPipePackets"; + case OpGroupReserveWritePipePackets: return "OpGroupReserveWritePipePackets"; + case OpGroupCommitReadPipe: return "OpGroupCommitReadPipe"; + case OpGroupCommitWritePipe: return "OpGroupCommitWritePipe"; + case OpEnqueueMarker: return "OpEnqueueMarker"; + case OpEnqueueKernel: return "OpEnqueueKernel"; + case OpGetKernelNDrangeSubGroupCount: return "OpGetKernelNDrangeSubGroupCount"; + case OpGetKernelNDrangeMaxSubGroupSize: return "OpGetKernelNDrangeMaxSubGroupSize"; + case OpGetKernelWorkGroupSize: return "OpGetKernelWorkGroupSize"; + case OpGetKernelPreferredWorkGroupSizeMultiple: return "OpGetKernelPreferredWorkGroupSizeMultiple"; + case OpRetainEvent: return "OpRetainEvent"; + case OpReleaseEvent: return "OpReleaseEvent"; + case OpCreateUserEvent: return "OpCreateUserEvent"; + case OpIsValidEvent: return "OpIsValidEvent"; + case OpSetUserEventStatus: return "OpSetUserEventStatus"; + case OpCaptureEventProfilingInfo: return "OpCaptureEventProfilingInfo"; + case OpGetDefaultQueue: return "OpGetDefaultQueue"; + case OpBuildNDRange: return "OpBuildNDRange"; + case OpImageSparseSampleImplicitLod: return "OpImageSparseSampleImplicitLod"; + case OpImageSparseSampleExplicitLod: return "OpImageSparseSampleExplicitLod"; + case OpImageSparseSampleDrefImplicitLod: return "OpImageSparseSampleDrefImplicitLod"; + case OpImageSparseSampleDrefExplicitLod: return "OpImageSparseSampleDrefExplicitLod"; + case OpImageSparseSampleProjImplicitLod: return "OpImageSparseSampleProjImplicitLod"; + case OpImageSparseSampleProjExplicitLod: return "OpImageSparseSampleProjExplicitLod"; + case OpImageSparseSampleProjDrefImplicitLod: return "OpImageSparseSampleProjDrefImplicitLod"; + case OpImageSparseSampleProjDrefExplicitLod: return "OpImageSparseSampleProjDrefExplicitLod"; + case OpImageSparseFetch: return "OpImageSparseFetch"; + case OpImageSparseGather: return "OpImageSparseGather"; + case OpImageSparseDrefGather: return "OpImageSparseDrefGather"; + case OpImageSparseTexelsResident: return "OpImageSparseTexelsResident"; + case OpNoLine: return "OpNoLine"; + case OpAtomicFlagTestAndSet: return "OpAtomicFlagTestAndSet"; + case OpAtomicFlagClear: return "OpAtomicFlagClear"; + case OpImageSparseRead: return "OpImageSparseRead"; + case OpSizeOf: return "OpSizeOf"; + case OpTypePipeStorage: return "OpTypePipeStorage"; + case OpConstantPipeStorage: return "OpConstantPipeStorage"; + case OpCreatePipeFromPipeStorage: return "OpCreatePipeFromPipeStorage"; + case OpGetKernelLocalSizeForSubgroupCount: return "OpGetKernelLocalSizeForSubgroupCount"; + case OpGetKernelMaxNumSubgroups: return "OpGetKernelMaxNumSubgroups"; + case OpTypeNamedBarrier: return "OpTypeNamedBarrier"; + case OpNamedBarrierInitialize: return "OpNamedBarrierInitialize"; + case OpMemoryNamedBarrier: return "OpMemoryNamedBarrier"; + case OpModuleProcessed: return "OpModuleProcessed"; + case OpExecutionModeId: return "OpExecutionModeId"; + case OpDecorateId: return "OpDecorateId"; + case OpGroupNonUniformElect: return "OpGroupNonUniformElect"; + case OpGroupNonUniformAll: return "OpGroupNonUniformAll"; + case OpGroupNonUniformAny: return "OpGroupNonUniformAny"; + case OpGroupNonUniformAllEqual: return "OpGroupNonUniformAllEqual"; + case OpGroupNonUniformBroadcast: return "OpGroupNonUniformBroadcast"; + case OpGroupNonUniformBroadcastFirst: return "OpGroupNonUniformBroadcastFirst"; + case OpGroupNonUniformBallot: return "OpGroupNonUniformBallot"; + case OpGroupNonUniformInverseBallot: return "OpGroupNonUniformInverseBallot"; + case OpGroupNonUniformBallotBitExtract: return "OpGroupNonUniformBallotBitExtract"; + case OpGroupNonUniformBallotBitCount: return "OpGroupNonUniformBallotBitCount"; + case OpGroupNonUniformBallotFindLSB: return "OpGroupNonUniformBallotFindLSB"; + case OpGroupNonUniformBallotFindMSB: return "OpGroupNonUniformBallotFindMSB"; + case OpGroupNonUniformShuffle: return "OpGroupNonUniformShuffle"; + case OpGroupNonUniformShuffleXor: return "OpGroupNonUniformShuffleXor"; + case OpGroupNonUniformShuffleUp: return "OpGroupNonUniformShuffleUp"; + case OpGroupNonUniformShuffleDown: return "OpGroupNonUniformShuffleDown"; + case OpGroupNonUniformIAdd: return "OpGroupNonUniformIAdd"; + case OpGroupNonUniformFAdd: return "OpGroupNonUniformFAdd"; + case OpGroupNonUniformIMul: return "OpGroupNonUniformIMul"; + case OpGroupNonUniformFMul: return "OpGroupNonUniformFMul"; + case OpGroupNonUniformSMin: return "OpGroupNonUniformSMin"; + case OpGroupNonUniformUMin: return "OpGroupNonUniformUMin"; + case OpGroupNonUniformFMin: return "OpGroupNonUniformFMin"; + case OpGroupNonUniformSMax: return "OpGroupNonUniformSMax"; + case OpGroupNonUniformUMax: return "OpGroupNonUniformUMax"; + case OpGroupNonUniformFMax: return "OpGroupNonUniformFMax"; + case OpGroupNonUniformBitwiseAnd: return "OpGroupNonUniformBitwiseAnd"; + case OpGroupNonUniformBitwiseOr: return "OpGroupNonUniformBitwiseOr"; + case OpGroupNonUniformBitwiseXor: return "OpGroupNonUniformBitwiseXor"; + case OpGroupNonUniformLogicalAnd: return "OpGroupNonUniformLogicalAnd"; + case OpGroupNonUniformLogicalOr: return "OpGroupNonUniformLogicalOr"; + case OpGroupNonUniformLogicalXor: return "OpGroupNonUniformLogicalXor"; + case OpGroupNonUniformQuadBroadcast: return "OpGroupNonUniformQuadBroadcast"; + case OpGroupNonUniformQuadSwap: return "OpGroupNonUniformQuadSwap"; + case OpCopyLogical: return "OpCopyLogical"; + case OpPtrEqual: return "OpPtrEqual"; + case OpPtrNotEqual: return "OpPtrNotEqual"; + case OpPtrDiff: return "OpPtrDiff"; + case OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + case OpTerminateInvocation: return "OpTerminateInvocation"; + case OpSubgroupBallotKHR: return "OpSubgroupBallotKHR"; + case OpSubgroupFirstInvocationKHR: return "OpSubgroupFirstInvocationKHR"; + case OpSubgroupAllKHR: return "OpSubgroupAllKHR"; + case OpSubgroupAnyKHR: return "OpSubgroupAnyKHR"; + case OpSubgroupAllEqualKHR: return "OpSubgroupAllEqualKHR"; + case OpGroupNonUniformRotateKHR: return "OpGroupNonUniformRotateKHR"; + case OpSubgroupReadInvocationKHR: return "OpSubgroupReadInvocationKHR"; + case OpExtInstWithForwardRefsKHR: return "OpExtInstWithForwardRefsKHR"; + case OpTraceRayKHR: return "OpTraceRayKHR"; + case OpExecuteCallableKHR: return "OpExecuteCallableKHR"; + case OpConvertUToAccelerationStructureKHR: return "OpConvertUToAccelerationStructureKHR"; + case OpIgnoreIntersectionKHR: return "OpIgnoreIntersectionKHR"; + case OpTerminateRayKHR: return "OpTerminateRayKHR"; + case OpSDot: return "OpSDot"; + case OpUDot: return "OpUDot"; + case OpSUDot: return "OpSUDot"; + case OpSDotAccSat: return "OpSDotAccSat"; + case OpUDotAccSat: return "OpUDotAccSat"; + case OpSUDotAccSat: return "OpSUDotAccSat"; + case OpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case OpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case OpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case OpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case OpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; + case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT"; + case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT"; + case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT"; + case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; + case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; + case OpRayQueryTerminateKHR: return "OpRayQueryTerminateKHR"; + case OpRayQueryGenerateIntersectionKHR: return "OpRayQueryGenerateIntersectionKHR"; + case OpRayQueryConfirmIntersectionKHR: return "OpRayQueryConfirmIntersectionKHR"; + case OpRayQueryProceedKHR: return "OpRayQueryProceedKHR"; + case OpRayQueryGetIntersectionTypeKHR: return "OpRayQueryGetIntersectionTypeKHR"; + case OpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case OpImageBlockMatchWindowSSDQCOM: return "OpImageBlockMatchWindowSSDQCOM"; + case OpImageBlockMatchWindowSADQCOM: return "OpImageBlockMatchWindowSADQCOM"; + case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; + case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; + case OpGroupIAddNonUniformAMD: return "OpGroupIAddNonUniformAMD"; + case OpGroupFAddNonUniformAMD: return "OpGroupFAddNonUniformAMD"; + case OpGroupFMinNonUniformAMD: return "OpGroupFMinNonUniformAMD"; + case OpGroupUMinNonUniformAMD: return "OpGroupUMinNonUniformAMD"; + case OpGroupSMinNonUniformAMD: return "OpGroupSMinNonUniformAMD"; + case OpGroupFMaxNonUniformAMD: return "OpGroupFMaxNonUniformAMD"; + case OpGroupUMaxNonUniformAMD: return "OpGroupUMaxNonUniformAMD"; + case OpGroupSMaxNonUniformAMD: return "OpGroupSMaxNonUniformAMD"; + case OpFragmentMaskFetchAMD: return "OpFragmentMaskFetchAMD"; + case OpFragmentFetchAMD: return "OpFragmentFetchAMD"; + case OpReadClockKHR: return "OpReadClockKHR"; + case OpFinalizeNodePayloadsAMDX: return "OpFinalizeNodePayloadsAMDX"; + case OpFinishWritingNodePayloadAMDX: return "OpFinishWritingNodePayloadAMDX"; + case OpInitializeNodePayloadsAMDX: return "OpInitializeNodePayloadsAMDX"; + case OpGroupNonUniformQuadAllKHR: return "OpGroupNonUniformQuadAllKHR"; + case OpGroupNonUniformQuadAnyKHR: return "OpGroupNonUniformQuadAnyKHR"; + case OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case OpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case OpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case OpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case OpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case OpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + case OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case OpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case OpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case OpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case OpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case OpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case OpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case OpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case OpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case OpHitObjectGetHitKindNV: return "OpHitObjectGetHitKindNV"; + case OpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case OpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case OpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case OpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case OpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case OpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case OpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case OpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case OpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case OpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case OpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case OpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case OpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case OpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; + case OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; + case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; + case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case OpReportIntersectionKHR: return "OpReportIntersectionKHR"; + case OpIgnoreIntersectionNV: return "OpIgnoreIntersectionNV"; + case OpTerminateRayNV: return "OpTerminateRayNV"; + case OpTraceNV: return "OpTraceNV"; + case OpTraceMotionNV: return "OpTraceMotionNV"; + case OpTraceRayMotionNV: return "OpTraceRayMotionNV"; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; + case OpTypeAccelerationStructureKHR: return "OpTypeAccelerationStructureKHR"; + case OpExecuteCallableNV: return "OpExecuteCallableNV"; + case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; + case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; + case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; + case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; + case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; + case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case OpDemoteToHelperInvocation: return "OpDemoteToHelperInvocation"; + case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; + case OpConvertUToImageNV: return "OpConvertUToImageNV"; + case OpConvertUToSamplerNV: return "OpConvertUToSamplerNV"; + case OpConvertImageToUNV: return "OpConvertImageToUNV"; + case OpConvertSamplerToUNV: return "OpConvertSamplerToUNV"; + case OpConvertUToSampledImageNV: return "OpConvertUToSampledImageNV"; + case OpConvertSampledImageToUNV: return "OpConvertSampledImageToUNV"; + case OpSamplerImageAddressingModeNV: return "OpSamplerImageAddressingModeNV"; + case OpRawAccessChainNV: return "OpRawAccessChainNV"; + case OpSubgroupShuffleINTEL: return "OpSubgroupShuffleINTEL"; + case OpSubgroupShuffleDownINTEL: return "OpSubgroupShuffleDownINTEL"; + case OpSubgroupShuffleUpINTEL: return "OpSubgroupShuffleUpINTEL"; + case OpSubgroupShuffleXorINTEL: return "OpSubgroupShuffleXorINTEL"; + case OpSubgroupBlockReadINTEL: return "OpSubgroupBlockReadINTEL"; + case OpSubgroupBlockWriteINTEL: return "OpSubgroupBlockWriteINTEL"; + case OpSubgroupImageBlockReadINTEL: return "OpSubgroupImageBlockReadINTEL"; + case OpSubgroupImageBlockWriteINTEL: return "OpSubgroupImageBlockWriteINTEL"; + case OpSubgroupImageMediaBlockReadINTEL: return "OpSubgroupImageMediaBlockReadINTEL"; + case OpSubgroupImageMediaBlockWriteINTEL: return "OpSubgroupImageMediaBlockWriteINTEL"; + case OpUCountLeadingZerosINTEL: return "OpUCountLeadingZerosINTEL"; + case OpUCountTrailingZerosINTEL: return "OpUCountTrailingZerosINTEL"; + case OpAbsISubINTEL: return "OpAbsISubINTEL"; + case OpAbsUSubINTEL: return "OpAbsUSubINTEL"; + case OpIAddSatINTEL: return "OpIAddSatINTEL"; + case OpUAddSatINTEL: return "OpUAddSatINTEL"; + case OpIAverageINTEL: return "OpIAverageINTEL"; + case OpUAverageINTEL: return "OpUAverageINTEL"; + case OpIAverageRoundedINTEL: return "OpIAverageRoundedINTEL"; + case OpUAverageRoundedINTEL: return "OpUAverageRoundedINTEL"; + case OpISubSatINTEL: return "OpISubSatINTEL"; + case OpUSubSatINTEL: return "OpUSubSatINTEL"; + case OpIMul32x16INTEL: return "OpIMul32x16INTEL"; + case OpUMul32x16INTEL: return "OpUMul32x16INTEL"; + case OpConstantFunctionPointerINTEL: return "OpConstantFunctionPointerINTEL"; + case OpFunctionPointerCallINTEL: return "OpFunctionPointerCallINTEL"; + case OpAsmTargetINTEL: return "OpAsmTargetINTEL"; + case OpAsmINTEL: return "OpAsmINTEL"; + case OpAsmCallINTEL: return "OpAsmCallINTEL"; + case OpAtomicFMinEXT: return "OpAtomicFMinEXT"; + case OpAtomicFMaxEXT: return "OpAtomicFMaxEXT"; + case OpAssumeTrueKHR: return "OpAssumeTrueKHR"; + case OpExpectKHR: return "OpExpectKHR"; + case OpDecorateString: return "OpDecorateString"; + case OpMemberDecorateString: return "OpMemberDecorateString"; + case OpVmeImageINTEL: return "OpVmeImageINTEL"; + case OpTypeVmeImageINTEL: return "OpTypeVmeImageINTEL"; + case OpTypeAvcImePayloadINTEL: return "OpTypeAvcImePayloadINTEL"; + case OpTypeAvcRefPayloadINTEL: return "OpTypeAvcRefPayloadINTEL"; + case OpTypeAvcSicPayloadINTEL: return "OpTypeAvcSicPayloadINTEL"; + case OpTypeAvcMcePayloadINTEL: return "OpTypeAvcMcePayloadINTEL"; + case OpTypeAvcMceResultINTEL: return "OpTypeAvcMceResultINTEL"; + case OpTypeAvcImeResultINTEL: return "OpTypeAvcImeResultINTEL"; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: return "OpTypeAvcImeResultSingleReferenceStreamoutINTEL"; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: return "OpTypeAvcImeResultDualReferenceStreamoutINTEL"; + case OpTypeAvcImeSingleReferenceStreaminINTEL: return "OpTypeAvcImeSingleReferenceStreaminINTEL"; + case OpTypeAvcImeDualReferenceStreaminINTEL: return "OpTypeAvcImeDualReferenceStreaminINTEL"; + case OpTypeAvcRefResultINTEL: return "OpTypeAvcRefResultINTEL"; + case OpTypeAvcSicResultINTEL: return "OpTypeAvcSicResultINTEL"; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: return "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL"; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: return "OpSubgroupAvcMceSetInterShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: return "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: return "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL"; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: return "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL"; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: return "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL"; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: return "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL"; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: return "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL"; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: return "OpSubgroupAvcMceSetAcOnlyHaarINTEL"; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: return "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL"; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcMceConvertToImePayloadINTEL: return "OpSubgroupAvcMceConvertToImePayloadINTEL"; + case OpSubgroupAvcMceConvertToImeResultINTEL: return "OpSubgroupAvcMceConvertToImeResultINTEL"; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: return "OpSubgroupAvcMceConvertToRefPayloadINTEL"; + case OpSubgroupAvcMceConvertToRefResultINTEL: return "OpSubgroupAvcMceConvertToRefResultINTEL"; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: return "OpSubgroupAvcMceConvertToSicPayloadINTEL"; + case OpSubgroupAvcMceConvertToSicResultINTEL: return "OpSubgroupAvcMceConvertToSicResultINTEL"; + case OpSubgroupAvcMceGetMotionVectorsINTEL: return "OpSubgroupAvcMceGetMotionVectorsINTEL"; + case OpSubgroupAvcMceGetInterDistortionsINTEL: return "OpSubgroupAvcMceGetInterDistortionsINTEL"; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: return "OpSubgroupAvcMceGetBestInterDistortionsINTEL"; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: return "OpSubgroupAvcMceGetInterMajorShapeINTEL"; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: return "OpSubgroupAvcMceGetInterMinorShapeINTEL"; + case OpSubgroupAvcMceGetInterDirectionsINTEL: return "OpSubgroupAvcMceGetInterDirectionsINTEL"; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: return "OpSubgroupAvcMceGetInterMotionVectorCountINTEL"; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: return "OpSubgroupAvcMceGetInterReferenceIdsINTEL"; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: return "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL"; + case OpSubgroupAvcImeInitializeINTEL: return "OpSubgroupAvcImeInitializeINTEL"; + case OpSubgroupAvcImeSetSingleReferenceINTEL: return "OpSubgroupAvcImeSetSingleReferenceINTEL"; + case OpSubgroupAvcImeSetDualReferenceINTEL: return "OpSubgroupAvcImeSetDualReferenceINTEL"; + case OpSubgroupAvcImeRefWindowSizeINTEL: return "OpSubgroupAvcImeRefWindowSizeINTEL"; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: return "OpSubgroupAvcImeAdjustRefOffsetINTEL"; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: return "OpSubgroupAvcImeConvertToMcePayloadINTEL"; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: return "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL"; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: return "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL"; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: return "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL"; + case OpSubgroupAvcImeSetWeightedSadINTEL: return "OpSubgroupAvcImeSetWeightedSadINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: return "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL"; + case OpSubgroupAvcImeConvertToMceResultINTEL: return "OpSubgroupAvcImeConvertToMceResultINTEL"; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: return "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL"; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: return "OpSubgroupAvcImeGetDualReferenceStreaminINTEL"; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL"; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: return "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL"; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: return "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL"; + case OpSubgroupAvcImeGetBorderReachedINTEL: return "OpSubgroupAvcImeGetBorderReachedINTEL"; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: return "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL"; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: return "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL"; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: return "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL"; + case OpSubgroupAvcFmeInitializeINTEL: return "OpSubgroupAvcFmeInitializeINTEL"; + case OpSubgroupAvcBmeInitializeINTEL: return "OpSubgroupAvcBmeInitializeINTEL"; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: return "OpSubgroupAvcRefConvertToMcePayloadINTEL"; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: return "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL"; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: return "OpSubgroupAvcRefSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcRefConvertToMceResultINTEL: return "OpSubgroupAvcRefConvertToMceResultINTEL"; + case OpSubgroupAvcSicInitializeINTEL: return "OpSubgroupAvcSicInitializeINTEL"; + case OpSubgroupAvcSicConfigureSkcINTEL: return "OpSubgroupAvcSicConfigureSkcINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaINTEL"; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: return "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL"; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: return "OpSubgroupAvcSicGetMotionVectorMaskINTEL"; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: return "OpSubgroupAvcSicConvertToMcePayloadINTEL"; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: return "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL"; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: return "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL"; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: return "OpSubgroupAvcSicSetBilinearFilterEnableINTEL"; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: return "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL"; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: return "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL"; + case OpSubgroupAvcSicEvaluateIpeINTEL: return "OpSubgroupAvcSicEvaluateIpeINTEL"; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL"; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: return "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL"; + case OpSubgroupAvcSicConvertToMceResultINTEL: return "OpSubgroupAvcSicConvertToMceResultINTEL"; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: return "OpSubgroupAvcSicGetIpeLumaShapeINTEL"; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL"; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: return "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL"; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: return "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL"; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: return "OpSubgroupAvcSicGetIpeChromaModeINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL"; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: return "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL"; + case OpSubgroupAvcSicGetInterRawSadsINTEL: return "OpSubgroupAvcSicGetInterRawSadsINTEL"; + case OpVariableLengthArrayINTEL: return "OpVariableLengthArrayINTEL"; + case OpSaveMemoryINTEL: return "OpSaveMemoryINTEL"; + case OpRestoreMemoryINTEL: return "OpRestoreMemoryINTEL"; + case OpArbitraryFloatSinCosPiINTEL: return "OpArbitraryFloatSinCosPiINTEL"; + case OpArbitraryFloatCastINTEL: return "OpArbitraryFloatCastINTEL"; + case OpArbitraryFloatCastFromIntINTEL: return "OpArbitraryFloatCastFromIntINTEL"; + case OpArbitraryFloatCastToIntINTEL: return "OpArbitraryFloatCastToIntINTEL"; + case OpArbitraryFloatAddINTEL: return "OpArbitraryFloatAddINTEL"; + case OpArbitraryFloatSubINTEL: return "OpArbitraryFloatSubINTEL"; + case OpArbitraryFloatMulINTEL: return "OpArbitraryFloatMulINTEL"; + case OpArbitraryFloatDivINTEL: return "OpArbitraryFloatDivINTEL"; + case OpArbitraryFloatGTINTEL: return "OpArbitraryFloatGTINTEL"; + case OpArbitraryFloatGEINTEL: return "OpArbitraryFloatGEINTEL"; + case OpArbitraryFloatLTINTEL: return "OpArbitraryFloatLTINTEL"; + case OpArbitraryFloatLEINTEL: return "OpArbitraryFloatLEINTEL"; + case OpArbitraryFloatEQINTEL: return "OpArbitraryFloatEQINTEL"; + case OpArbitraryFloatRecipINTEL: return "OpArbitraryFloatRecipINTEL"; + case OpArbitraryFloatRSqrtINTEL: return "OpArbitraryFloatRSqrtINTEL"; + case OpArbitraryFloatCbrtINTEL: return "OpArbitraryFloatCbrtINTEL"; + case OpArbitraryFloatHypotINTEL: return "OpArbitraryFloatHypotINTEL"; + case OpArbitraryFloatSqrtINTEL: return "OpArbitraryFloatSqrtINTEL"; + case OpArbitraryFloatLogINTEL: return "OpArbitraryFloatLogINTEL"; + case OpArbitraryFloatLog2INTEL: return "OpArbitraryFloatLog2INTEL"; + case OpArbitraryFloatLog10INTEL: return "OpArbitraryFloatLog10INTEL"; + case OpArbitraryFloatLog1pINTEL: return "OpArbitraryFloatLog1pINTEL"; + case OpArbitraryFloatExpINTEL: return "OpArbitraryFloatExpINTEL"; + case OpArbitraryFloatExp2INTEL: return "OpArbitraryFloatExp2INTEL"; + case OpArbitraryFloatExp10INTEL: return "OpArbitraryFloatExp10INTEL"; + case OpArbitraryFloatExpm1INTEL: return "OpArbitraryFloatExpm1INTEL"; + case OpArbitraryFloatSinINTEL: return "OpArbitraryFloatSinINTEL"; + case OpArbitraryFloatCosINTEL: return "OpArbitraryFloatCosINTEL"; + case OpArbitraryFloatSinCosINTEL: return "OpArbitraryFloatSinCosINTEL"; + case OpArbitraryFloatSinPiINTEL: return "OpArbitraryFloatSinPiINTEL"; + case OpArbitraryFloatCosPiINTEL: return "OpArbitraryFloatCosPiINTEL"; + case OpArbitraryFloatASinINTEL: return "OpArbitraryFloatASinINTEL"; + case OpArbitraryFloatASinPiINTEL: return "OpArbitraryFloatASinPiINTEL"; + case OpArbitraryFloatACosINTEL: return "OpArbitraryFloatACosINTEL"; + case OpArbitraryFloatACosPiINTEL: return "OpArbitraryFloatACosPiINTEL"; + case OpArbitraryFloatATanINTEL: return "OpArbitraryFloatATanINTEL"; + case OpArbitraryFloatATanPiINTEL: return "OpArbitraryFloatATanPiINTEL"; + case OpArbitraryFloatATan2INTEL: return "OpArbitraryFloatATan2INTEL"; + case OpArbitraryFloatPowINTEL: return "OpArbitraryFloatPowINTEL"; + case OpArbitraryFloatPowRINTEL: return "OpArbitraryFloatPowRINTEL"; + case OpArbitraryFloatPowNINTEL: return "OpArbitraryFloatPowNINTEL"; + case OpLoopControlINTEL: return "OpLoopControlINTEL"; + case OpAliasDomainDeclINTEL: return "OpAliasDomainDeclINTEL"; + case OpAliasScopeDeclINTEL: return "OpAliasScopeDeclINTEL"; + case OpAliasScopeListDeclINTEL: return "OpAliasScopeListDeclINTEL"; + case OpFixedSqrtINTEL: return "OpFixedSqrtINTEL"; + case OpFixedRecipINTEL: return "OpFixedRecipINTEL"; + case OpFixedRsqrtINTEL: return "OpFixedRsqrtINTEL"; + case OpFixedSinINTEL: return "OpFixedSinINTEL"; + case OpFixedCosINTEL: return "OpFixedCosINTEL"; + case OpFixedSinCosINTEL: return "OpFixedSinCosINTEL"; + case OpFixedSinPiINTEL: return "OpFixedSinPiINTEL"; + case OpFixedCosPiINTEL: return "OpFixedCosPiINTEL"; + case OpFixedSinCosPiINTEL: return "OpFixedSinCosPiINTEL"; + case OpFixedLogINTEL: return "OpFixedLogINTEL"; + case OpFixedExpINTEL: return "OpFixedExpINTEL"; + case OpPtrCastToCrossWorkgroupINTEL: return "OpPtrCastToCrossWorkgroupINTEL"; + case OpCrossWorkgroupCastToPtrINTEL: return "OpCrossWorkgroupCastToPtrINTEL"; + case OpReadPipeBlockingINTEL: return "OpReadPipeBlockingINTEL"; + case OpWritePipeBlockingINTEL: return "OpWritePipeBlockingINTEL"; + case OpFPGARegINTEL: return "OpFPGARegINTEL"; + case OpRayQueryGetRayTMinKHR: return "OpRayQueryGetRayTMinKHR"; + case OpRayQueryGetRayFlagsKHR: return "OpRayQueryGetRayFlagsKHR"; + case OpRayQueryGetIntersectionTKHR: return "OpRayQueryGetIntersectionTKHR"; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: return "OpRayQueryGetIntersectionInstanceCustomIndexKHR"; + case OpRayQueryGetIntersectionInstanceIdKHR: return "OpRayQueryGetIntersectionInstanceIdKHR"; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: return "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR"; + case OpRayQueryGetIntersectionGeometryIndexKHR: return "OpRayQueryGetIntersectionGeometryIndexKHR"; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: return "OpRayQueryGetIntersectionPrimitiveIndexKHR"; + case OpRayQueryGetIntersectionBarycentricsKHR: return "OpRayQueryGetIntersectionBarycentricsKHR"; + case OpRayQueryGetIntersectionFrontFaceKHR: return "OpRayQueryGetIntersectionFrontFaceKHR"; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: return "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR"; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: return "OpRayQueryGetIntersectionObjectRayDirectionKHR"; + case OpRayQueryGetIntersectionObjectRayOriginKHR: return "OpRayQueryGetIntersectionObjectRayOriginKHR"; + case OpRayQueryGetWorldRayDirectionKHR: return "OpRayQueryGetWorldRayDirectionKHR"; + case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; + case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; + case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case OpAtomicFAddEXT: return "OpAtomicFAddEXT"; + case OpTypeBufferSurfaceINTEL: return "OpTypeBufferSurfaceINTEL"; + case OpTypeStructContinuedINTEL: return "OpTypeStructContinuedINTEL"; + case OpConstantCompositeContinuedINTEL: return "OpConstantCompositeContinuedINTEL"; + case OpSpecConstantCompositeContinuedINTEL: return "OpSpecConstantCompositeContinuedINTEL"; + case OpCompositeConstructContinuedINTEL: return "OpCompositeConstructContinuedINTEL"; + case OpConvertFToBF16INTEL: return "OpConvertFToBF16INTEL"; + case OpConvertBF16ToFINTEL: return "OpConvertBF16ToFINTEL"; + case OpControlBarrierArriveINTEL: return "OpControlBarrierArriveINTEL"; + case OpControlBarrierWaitINTEL: return "OpControlBarrierWaitINTEL"; + case OpGroupIMulKHR: return "OpGroupIMulKHR"; + case OpGroupFMulKHR: return "OpGroupFMulKHR"; + case OpGroupBitwiseAndKHR: return "OpGroupBitwiseAndKHR"; + case OpGroupBitwiseOrKHR: return "OpGroupBitwiseOrKHR"; + case OpGroupBitwiseXorKHR: return "OpGroupBitwiseXorKHR"; + case OpGroupLogicalAndKHR: return "OpGroupLogicalAndKHR"; + case OpGroupLogicalOrKHR: return "OpGroupLogicalOrKHR"; + case OpGroupLogicalXorKHR: return "OpGroupLogicalXorKHR"; + case OpMaskedGatherINTEL: return "OpMaskedGatherINTEL"; + case OpMaskedScatterINTEL: return "OpMaskedScatterINTEL"; + default: return "Unknown"; + } +} + #endif /* SPV_ENABLE_UTILITY_CODE */ // Overload bitwise operators for mask bit combining @@ -2908,6 +4725,10 @@ constexpr CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask constexpr CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } constexpr CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } constexpr CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } +constexpr RawAccessChainOperandsMask operator|(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) | unsigned(b)); } +constexpr RawAccessChainOperandsMask operator&(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) & unsigned(b)); } +constexpr RawAccessChainOperandsMask operator^(RawAccessChainOperandsMask a, RawAccessChainOperandsMask b) { return RawAccessChainOperandsMask(unsigned(a) ^ unsigned(b)); } +constexpr RawAccessChainOperandsMask operator~(RawAccessChainOperandsMask a) { return RawAccessChainOperandsMask(~unsigned(a)); } } // end namespace spv diff --git a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json index a47a1f6..430c74f 100644 --- a/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json +++ b/libs/bgfx/3rdparty/spirv-headers/include/spirv/unified1/spirv.json @@ -233,7 +233,10 @@ "FPFastMathDefault": 6028, "StreamingInterfaceINTEL": 6154, "RegisterMapInterfaceINTEL": 6160, - "NamedBarrierCountINTEL": 6417 + "NamedBarrierCountINTEL": 6417, + "MaximumRegistersINTEL": 6461, + "MaximumRegistersIdINTEL": 6462, + "NamedMaximumRegistersINTEL": 6463 } }, { @@ -1019,6 +1022,7 @@ "TileImageColorReadAccessEXT": 4166, "TileImageDepthReadAccessEXT": 4167, "TileImageStencilReadAccessEXT": 4168, + "CooperativeMatrixLayoutsARM": 4201, "FragmentShadingRateKHR": 4422, "SubgroupBallotKHR": 4423, "DrawParameters": 4427, @@ -1129,6 +1133,7 @@ "RayQueryPositionFetchKHR": 5391, "AtomicFloat16VectorNV": 5404, "RayTracingDisplacementMicromapNV": 5409, + "RawAccessChainsNV": 5414, "SubgroupShuffleINTEL": 5568, "SubgroupBufferBlockIOINTEL": 5569, "SubgroupImageBlockIOINTEL": 5570, @@ -1181,6 +1186,7 @@ "DotProductKHR": 6019, "RayCullMaskKHR": 6020, "CooperativeMatrixKHR": 6022, + "ReplicatedCompositesEXT": 6024, "BitInstructions": 6025, "GroupNonUniformRotateKHR": 6026, "FloatControls2": 6029, @@ -1201,7 +1207,8 @@ "GlobalVariableFPGADecorationsINTEL": 6189, "GroupUniformArithmeticKHR": 6400, "MaskedGatherScatterINTEL": 6427, - "CacheControlsINTEL": 6441 + "CacheControlsINTEL": 6441, + "RegisterLimitsINTEL": 6460 } }, { @@ -1332,7 +1339,9 @@ "Values": { "RowMajorKHR": 0, - "ColumnMajorKHR": 1 + "ColumnMajorKHR": 1, + "RowBlockedInterleavedARM": 4202, + "ColumnBlockedInterleavedARM": 4203 } }, { @@ -1388,6 +1397,23 @@ "StreamingINTEL": 3 } }, + { + "Name": "NamedMaximumNumberOfRegisters", + "Type": "Value", + "Values": + { + "AutoINTEL": 0 + } + }, + { + "Name": "RawAccessChainOperands", + "Type": "Bit", + "Values": + { + "RobustnessPerComponentNV": 0, + "RobustnessPerElementNV": 1 + } + }, { "Name": "Op", "Type": "Value", @@ -1748,6 +1774,7 @@ "OpSubgroupAllEqualKHR": 4430, "OpGroupNonUniformRotateKHR": 4431, "OpSubgroupReadInvocationKHR": 4432, + "OpExtInstWithForwardRefsKHR": 4433, "OpTraceRayKHR": 4445, "OpExecuteCallableKHR": 4446, "OpConvertUToAccelerationStructureKHR": 4447, @@ -1770,6 +1797,9 @@ "OpCooperativeMatrixStoreKHR": 4458, "OpCooperativeMatrixMulAddKHR": 4459, "OpCooperativeMatrixLengthKHR": 4460, + "OpConstantCompositeReplicateEXT": 4461, + "OpSpecConstantCompositeReplicateEXT": 4462, + "OpCompositeConstructReplicateEXT": 4463, "OpTypeRayQueryKHR": 4472, "OpRayQueryInitializeKHR": 4473, "OpRayQueryTerminateKHR": 4474, @@ -1869,6 +1899,7 @@ "OpConvertUToSampledImageNV": 5395, "OpConvertSampledImageToUNV": 5396, "OpSamplerImageAddressingModeNV": 5397, + "OpRawAccessChainNV": 5398, "OpSubgroupShuffleINTEL": 5571, "OpSubgroupShuffleDownINTEL": 5572, "OpSubgroupShuffleUpINTEL": 5573, diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc index 3965da8..043e206 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/build-version.inc @@ -1 +1 @@ -"v2023.6", "SPIRV-Tools v2023.6 v2023.6.rc1-53-g0b935b1d" +"v2024.2", "SPIRV-Tools v2024.2 v2024.2.rc1-28-gf2bbb12a" diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc index 85e2f19..5550ea5 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/core.insts-unified1.inc @@ -53,6 +53,7 @@ static const spv::Capability pygen_variable_caps_NamedBarrier[] = {spv::Capabili static const spv::Capability pygen_variable_caps_PipeStorage[] = {spv::Capability::PipeStorage}; static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; static const spv::Capability pygen_variable_caps_QuadControlKHR[] = {spv::Capability::QuadControlKHR}; +static const spv::Capability pygen_variable_caps_RawAccessChainsNV[] = {spv::Capability::RawAccessChainsNV}; static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; static const spv::Capability pygen_variable_caps_RayQueryPositionFetchKHR[] = {spv::Capability::RayQueryPositionFetchKHR}; static const spv::Capability pygen_variable_caps_RayTracingKHR[] = {spv::Capability::RayTracingKHR}; @@ -61,6 +62,7 @@ static const spv::Capability pygen_variable_caps_RayTracingMotionBlurNV[] = {spv static const spv::Capability pygen_variable_caps_RayTracingNV[] = {spv::Capability::RayTracingNV}; static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR}; static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHRRayQueryKHR[] = {spv::Capability::RayTracingNV, spv::Capability::RayTracingKHR, spv::Capability::RayQueryKHR}; +static const spv::Capability pygen_variable_caps_ReplicatedCompositesEXT[] = {spv::Capability::ReplicatedCompositesEXT}; static const spv::Capability pygen_variable_caps_Shader[] = {spv::Capability::Shader}; static const spv::Capability pygen_variable_caps_ShaderBitInstructions[] = {spv::Capability::Shader, spv::Capability::BitInstructions}; static const spv::Capability pygen_variable_caps_ShaderClockKHR[] = {spv::Capability::ShaderClockKHR}; @@ -108,6 +110,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_KHR_integer_dot_product static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_query}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracing[] = {spvtools::Extension::kSPV_KHR_ray_tracing}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query[] = {spvtools::Extension::kSPV_KHR_ray_tracing, spvtools::Extension::kSPV_KHR_ray_query}; +static const spvtools::Extension pygen_variable_exts_SPV_KHR_relaxed_extended_instruction[] = {spvtools::Extension::kSPV_KHR_relaxed_extended_instruction}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_shader_ballot[] = {spvtools::Extension::kSPV_KHR_shader_ballot}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_subgroup_vote[] = {spvtools::Extension::kSPV_KHR_subgroup_vote}; static const spvtools::Extension pygen_variable_exts_SPV_KHR_terminate_invocation[] = {spvtools::Extension::kSPV_KHR_terminate_invocation}; @@ -476,6 +479,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"SubgroupAllEqualKHR", spv::Op::OpSubgroupAllEqualKHR, 1, pygen_variable_caps_SubgroupVoteKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_subgroup_vote, 0xffffffffu, 0xffffffffu}, {"GroupNonUniformRotateKHR", spv::Op::OpGroupNonUniformRotateKHR, 1, pygen_variable_caps_GroupNonUniformRotateKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_SCOPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupReadInvocationKHR", spv::Op::OpSubgroupReadInvocationKHR, 1, pygen_variable_caps_SubgroupBallotKHR, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_shader_ballot, 0xffffffffu, 0xffffffffu}, + {"ExtInstWithForwardRefsKHR", spv::Op::OpExtInstWithForwardRefsKHR, 0, nullptr, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER, SPV_OPERAND_TYPE_VARIABLE_ID}, 1, 1, 1, pygen_variable_exts_SPV_KHR_relaxed_extended_instruction, 0xffffffffu, 0xffffffffu}, {"TraceRayKHR", spv::Op::OpTraceRayKHR, 1, pygen_variable_caps_RayTracingKHR, 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_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, {"ExecuteCallableKHR", spv::Op::OpExecuteCallableKHR, 1, pygen_variable_caps_RayTracingKHR, 2, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_tracing, 0xffffffffu, 0xffffffffu}, {"ConvertUToAccelerationStructureKHR", spv::Op::OpConvertUToAccelerationStructureKHR, 2, pygen_variable_caps_RayTracingKHRRayQueryKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, @@ -498,6 +502,9 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"CooperativeMatrixStoreKHR", spv::Op::OpCooperativeMatrixStoreKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 5, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_ID, SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"CooperativeMatrixMulAddKHR", spv::Op::OpCooperativeMatrixMulAddKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 6, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"CooperativeMatrixLengthKHR", spv::Op::OpCooperativeMatrixLengthKHR, 1, pygen_variable_caps_CooperativeMatrixKHR, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"ConstantCompositeReplicateEXT", spv::Op::OpConstantCompositeReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"SpecConstantCompositeReplicateEXT", spv::Op::OpSpecConstantCompositeReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"CompositeConstructReplicateEXT", spv::Op::OpCompositeConstructReplicateEXT, 1, pygen_variable_caps_ReplicatedCompositesEXT, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"TypeRayQueryKHR", spv::Op::OpTypeRayQueryKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_RESULT_ID}, 1, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, {"RayQueryInitializeKHR", spv::Op::OpRayQueryInitializeKHR, 1, pygen_variable_caps_RayQueryKHR, 8, {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_KHR_ray_query, 0xffffffffu, 0xffffffffu}, {"RayQueryTerminateKHR", spv::Op::OpRayQueryTerminateKHR, 1, pygen_variable_caps_RayQueryKHR, 1, {SPV_OPERAND_TYPE_ID}, 0, 0, 1, pygen_variable_exts_SPV_KHR_ray_query, 0xffffffffu, 0xffffffffu}, @@ -597,6 +604,7 @@ static const spv_opcode_desc_t kOpcodeTableEntries[] = { {"ConvertUToSampledImageNV", spv::Op::OpConvertUToSampledImageNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"ConvertSampledImageToUNV", spv::Op::OpConvertSampledImageToUNV, 1, pygen_variable_caps_BindlessTextureNV, 3, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SamplerImageAddressingModeNV", spv::Op::OpSamplerImageAddressingModeNV, 1, pygen_variable_caps_BindlessTextureNV, 1, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0, 0, 0, nullptr, 0xffffffffu, 0xffffffffu}, + {"RawAccessChainNV", spv::Op::OpRawAccessChainNV, 1, pygen_variable_caps_RawAccessChainsNV, 7, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupShuffleINTEL", spv::Op::OpSubgroupShuffleINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 4, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupShuffleDownINTEL", spv::Op::OpSubgroupShuffleDownINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, {"SubgroupShuffleUpINTEL", spv::Op::OpSubgroupShuffleUpINTEL, 1, pygen_variable_caps_SubgroupShuffleINTEL, 5, {SPV_OPERAND_TYPE_TYPE_ID, SPV_OPERAND_TYPE_RESULT_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 1, 1, 0, nullptr, 0xffffffffu, 0xffffffffu}, diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc index b8cbf2b..a93c413 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/enum_string_mapping.inc @@ -24,6 +24,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_AMD_shader_trinary_minmax"; case Extension::kSPV_AMD_texture_gather_bias_lod: return "SPV_AMD_texture_gather_bias_lod"; + case Extension::kSPV_ARM_cooperative_matrix_layouts: + return "SPV_ARM_cooperative_matrix_layouts"; case Extension::kSPV_ARM_core_builtins: return "SPV_ARM_core_builtins"; case Extension::kSPV_EXT_demote_to_helper_invocation: @@ -42,6 +44,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_EXT_opacity_micromap"; case Extension::kSPV_EXT_physical_storage_buffer: return "SPV_EXT_physical_storage_buffer"; + case Extension::kSPV_EXT_replicated_composites: + return "SPV_EXT_replicated_composites"; case Extension::kSPV_EXT_shader_atomic_float16_add: return "SPV_EXT_shader_atomic_float16_add"; case Extension::kSPV_EXT_shader_atomic_float_add: @@ -122,6 +126,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_INTEL_loop_fuse"; case Extension::kSPV_INTEL_masked_gather_scatter: return "SPV_INTEL_masked_gather_scatter"; + case Extension::kSPV_INTEL_maximum_registers: + return "SPV_INTEL_maximum_registers"; case Extension::kSPV_INTEL_media_block_io: return "SPV_INTEL_media_block_io"; case Extension::kSPV_INTEL_memory_access_aliasing: @@ -190,6 +196,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_KHR_ray_tracing"; case Extension::kSPV_KHR_ray_tracing_position_fetch: return "SPV_KHR_ray_tracing_position_fetch"; + case Extension::kSPV_KHR_relaxed_extended_instruction: + return "SPV_KHR_relaxed_extended_instruction"; case Extension::kSPV_KHR_shader_atomic_counter_ops: return "SPV_KHR_shader_atomic_counter_ops"; case Extension::kSPV_KHR_shader_ballot: @@ -232,6 +240,8 @@ const char* ExtensionToString(Extension extension) { return "SPV_NV_geometry_shader_passthrough"; case Extension::kSPV_NV_mesh_shader: return "SPV_NV_mesh_shader"; + case Extension::kSPV_NV_raw_access_chains: + return "SPV_NV_raw_access_chains"; case Extension::kSPV_NV_ray_tracing: return "SPV_NV_ray_tracing"; case Extension::kSPV_NV_ray_tracing_motion_blur: @@ -267,8 +277,8 @@ const char* ExtensionToString(Extension extension) { bool GetExtensionFromString(const char* str, Extension* extension) { - static const char* known_ext_strs[] = { "SPV_AMDX_shader_enqueue", "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_early_and_late_fragment_tests", "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_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "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_tile_image", "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_bfloat16_conversion", "SPV_INTEL_blocking_pipes", "SPV_INTEL_cache_controls", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fp_max_error", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_latency_control", "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_global_variable_fpga_decorations", "SPV_INTEL_global_variable_host_access", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_composites", "SPV_INTEL_loop_fuse", "SPV_INTEL_masked_gather_scatter", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "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_cooperative_matrix", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_float_controls2", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_maximal_reconvergence", "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_quad_control", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_ray_tracing_position_fetch", "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_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_displacement_micromap", "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_atomic_fp16_vector", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_QCOM_image_processing", "SPV_QCOM_image_processing2", "SPV_VALIDATOR_ignore_type_decl_unique" }; - static const Extension known_ext_ids[] = { Extension::kSPV_AMDX_shader_enqueue, 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_early_and_late_fragment_tests, 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_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, 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_tile_image, 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_bfloat16_conversion, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_cache_controls, 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_fp_max_error, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_latency_control, 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_global_variable_fpga_decorations, Extension::kSPV_INTEL_global_variable_host_access, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_composites, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_masked_gather_scatter, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, 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_cooperative_matrix, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_float_controls2, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_maximal_reconvergence, 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_quad_control, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_ray_tracing_position_fetch, 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_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, 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_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_displacement_micromap, 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_atomic_fp16_vector, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, 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_QCOM_image_processing, Extension::kSPV_QCOM_image_processing2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique }; + static const char* known_ext_strs[] = { "SPV_AMDX_shader_enqueue", "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_early_and_late_fragment_tests", "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_ARM_cooperative_matrix_layouts", "SPV_ARM_core_builtins", "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_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_replicated_composites", "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_tile_image", "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_bfloat16_conversion", "SPV_INTEL_blocking_pipes", "SPV_INTEL_cache_controls", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fp_max_error", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_latency_control", "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_global_variable_fpga_decorations", "SPV_INTEL_global_variable_host_access", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_composites", "SPV_INTEL_loop_fuse", "SPV_INTEL_masked_gather_scatter", "SPV_INTEL_maximum_registers", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "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_cooperative_matrix", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_float_controls2", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_maximal_reconvergence", "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_quad_control", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_ray_tracing_position_fetch", "SPV_KHR_relaxed_extended_instruction", "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_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_displacement_micromap", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_raw_access_chains", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_atomic_fp16_vector", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_QCOM_image_processing", "SPV_QCOM_image_processing2", "SPV_VALIDATOR_ignore_type_decl_unique" }; + static const Extension known_ext_ids[] = { Extension::kSPV_AMDX_shader_enqueue, 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_early_and_late_fragment_tests, 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_ARM_cooperative_matrix_layouts, Extension::kSPV_ARM_core_builtins, 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_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_replicated_composites, 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_tile_image, 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_bfloat16_conversion, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_cache_controls, 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_fp_max_error, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_latency_control, 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_global_variable_fpga_decorations, Extension::kSPV_INTEL_global_variable_host_access, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_composites, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_masked_gather_scatter, Extension::kSPV_INTEL_maximum_registers, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, 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_cooperative_matrix, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_float_controls2, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_maximal_reconvergence, 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_quad_control, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_ray_tracing_position_fetch, Extension::kSPV_KHR_relaxed_extended_instruction, 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_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, 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_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_displacement_micromap, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_raw_access_chains, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_atomic_fp16_vector, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, 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_QCOM_image_processing, Extension::kSPV_QCOM_image_processing2, 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( @@ -432,6 +442,8 @@ const char* CapabilityToString(spv::Capability capability) { return "TileImageDepthReadAccessEXT"; case spv::Capability::TileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case spv::Capability::CooperativeMatrixLayoutsARM: + return "CooperativeMatrixLayoutsARM"; case spv::Capability::FragmentShadingRateKHR: return "FragmentShadingRateKHR"; case spv::Capability::SubgroupBallotKHR: @@ -610,6 +622,8 @@ const char* CapabilityToString(spv::Capability capability) { return "AtomicFloat16VectorNV"; case spv::Capability::RayTracingDisplacementMicromapNV: return "RayTracingDisplacementMicromapNV"; + case spv::Capability::RawAccessChainsNV: + return "RawAccessChainsNV"; case spv::Capability::SubgroupShuffleINTEL: return "SubgroupShuffleINTEL"; case spv::Capability::SubgroupBufferBlockIOINTEL: @@ -706,6 +720,8 @@ const char* CapabilityToString(spv::Capability capability) { return "RayCullMaskKHR"; case spv::Capability::CooperativeMatrixKHR: return "CooperativeMatrixKHR"; + case spv::Capability::ReplicatedCompositesEXT: + return "ReplicatedCompositesEXT"; case spv::Capability::BitInstructions: return "BitInstructions"; case spv::Capability::GroupNonUniformRotateKHR: @@ -748,6 +764,8 @@ const char* CapabilityToString(spv::Capability capability) { return "MaskedGatherScatterINTEL"; case spv::Capability::CacheControlsINTEL: return "CacheControlsINTEL"; + case spv::Capability::RegisterLimitsINTEL: + return "RegisterLimitsINTEL"; case spv::Capability::Max: assert(0 && "Attempting to convert spv::Capability::Max to string"); return ""; diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc index 1f8a455..ac42c58 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/extension_enum.inc @@ -10,6 +10,7 @@ kSPV_AMD_shader_fragment_mask, kSPV_AMD_shader_image_load_store_lod, kSPV_AMD_shader_trinary_minmax, kSPV_AMD_texture_gather_bias_lod, +kSPV_ARM_cooperative_matrix_layouts, kSPV_ARM_core_builtins, kSPV_EXT_demote_to_helper_invocation, kSPV_EXT_descriptor_indexing, @@ -19,6 +20,7 @@ kSPV_EXT_fragment_shader_interlock, kSPV_EXT_mesh_shader, kSPV_EXT_opacity_micromap, kSPV_EXT_physical_storage_buffer, +kSPV_EXT_replicated_composites, kSPV_EXT_shader_atomic_float16_add, kSPV_EXT_shader_atomic_float_add, kSPV_EXT_shader_atomic_float_min_max, @@ -59,6 +61,7 @@ kSPV_INTEL_kernel_attributes, kSPV_INTEL_long_composites, kSPV_INTEL_loop_fuse, kSPV_INTEL_masked_gather_scatter, +kSPV_INTEL_maximum_registers, kSPV_INTEL_media_block_io, kSPV_INTEL_memory_access_aliasing, kSPV_INTEL_optnone, @@ -93,6 +96,7 @@ kSPV_KHR_ray_cull_mask, kSPV_KHR_ray_query, kSPV_KHR_ray_tracing, kSPV_KHR_ray_tracing_position_fetch, +kSPV_KHR_relaxed_extended_instruction, kSPV_KHR_shader_atomic_counter_ops, kSPV_KHR_shader_ballot, kSPV_KHR_shader_clock, @@ -114,6 +118,7 @@ kSPV_NV_displacement_micromap, kSPV_NV_fragment_shader_barycentric, kSPV_NV_geometry_shader_passthrough, kSPV_NV_mesh_shader, +kSPV_NV_raw_access_chains, kSPV_NV_ray_tracing, kSPV_NV_ray_tracing_motion_blur, kSPV_NV_sample_mask_override_coverage, diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/generators.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/generators.inc index 34f120f..e67e575 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/generators.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/generators.inc @@ -39,4 +39,6 @@ {38, "Meta", "SparkSL", "Meta SparkSL"}, {39, "SirLynix", "Nazara ShaderLang Compiler", "SirLynix Nazara ShaderLang Compiler"}, {40, "NVIDIA", "Slang Compiler", "NVIDIA Slang Compiler"}, -{41, "Zig Software Foundation", "Zig Compiler", "Zig Software Foundation Zig Compiler"}, \ No newline at end of file +{41, "Zig Software Foundation", "Zig Compiler", "Zig Software Foundation Zig Compiler"}, +{42, "Rendong Liang", "spq", "Rendong Liang spq"}, +{43, "LLVM", "LLVM SPIR-V Backend", "LLVM LLVM SPIR-V Backend"}, \ No newline at end of file diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vkspreflection.insts.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vkspreflection.insts.inc new file mode 100644 index 0000000..623b9cf --- /dev/null +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/nonsemantic.vkspreflection.insts.inc @@ -0,0 +1,12 @@ + + +static const spv_ext_inst_desc_t nonsemantic_vkspreflection_entries[] = { + {"Configuration", 1, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"StartCounter", 2, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_NONE}}, + {"StopCounter", 3, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_NONE}}, + {"PushConstants", 4, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_STRING, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"SpecializationMapEntry", 5, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DescriptorSetBuffer", 6, 0, nullptr, {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, 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, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DescriptorSetImage", 7, 0, nullptr, {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, 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, 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, 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, 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, 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, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}}, + {"DescriptorSetSampler", 8, 0, nullptr, {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, 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, SPV_OPERAND_TYPE_LITERAL_FLOAT, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_FLOAT, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_FLOAT, SPV_OPERAND_TYPE_LITERAL_FLOAT, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_LITERAL_INTEGER, SPV_OPERAND_TYPE_NONE}} +}; \ No newline at end of file diff --git a/libs/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc b/libs/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc index 24514cb..ccfd69a 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc +++ b/libs/bgfx/3rdparty/spirv-tools/include/generated/operand.kinds-unified1.inc @@ -86,6 +86,7 @@ static const spv::Capability pygen_variable_caps_PerViewAttributesNVMeshShadingN static const spv::Capability pygen_variable_caps_PhysicalStorageBufferAddresses[] = {spv::Capability::PhysicalStorageBufferAddresses}; static const spv::Capability pygen_variable_caps_Pipes[] = {spv::Capability::Pipes}; static const spv::Capability pygen_variable_caps_QuadControlKHR[] = {spv::Capability::QuadControlKHR}; +static const spv::Capability pygen_variable_caps_RawAccessChainsNV[] = {spv::Capability::RawAccessChainsNV}; static const spv::Capability pygen_variable_caps_RayCullMaskKHR[] = {spv::Capability::RayCullMaskKHR}; static const spv::Capability pygen_variable_caps_RayQueryKHR[] = {spv::Capability::RayQueryKHR}; static const spv::Capability pygen_variable_caps_RayQueryKHRRayTracingKHR[] = {spv::Capability::RayQueryKHR, spv::Capability::RayTracingKHR}; @@ -97,6 +98,7 @@ static const spv::Capability pygen_variable_caps_RayTracingNVRayTracingKHR[] = { static const spv::Capability pygen_variable_caps_RayTracingOpacityMicromapEXT[] = {spv::Capability::RayTracingOpacityMicromapEXT}; static const spv::Capability pygen_variable_caps_RayTracingPositionFetchKHR[] = {spv::Capability::RayTracingPositionFetchKHR}; static const spv::Capability pygen_variable_caps_RayTraversalPrimitiveCullingKHR[] = {spv::Capability::RayTraversalPrimitiveCullingKHR}; +static const spv::Capability pygen_variable_caps_RegisterLimitsINTEL[] = {spv::Capability::RegisterLimitsINTEL}; static const spv::Capability pygen_variable_caps_RoundToInfinityINTEL[] = {spv::Capability::RoundToInfinityINTEL}; static const spv::Capability pygen_variable_caps_RoundingModeRTE[] = {spv::Capability::RoundingModeRTE}; static const spv::Capability pygen_variable_caps_RoundingModeRTZ[] = {spv::Capability::RoundingModeRTZ}; @@ -150,6 +152,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_explicit_ver static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_fragment_mask[] = {spvtools::Extension::kSPV_AMD_shader_fragment_mask}; static const spvtools::Extension pygen_variable_exts_SPV_AMD_shader_image_load_store_lod[] = {spvtools::Extension::kSPV_AMD_shader_image_load_store_lod}; static const spvtools::Extension pygen_variable_exts_SPV_AMD_texture_gather_bias_lod[] = {spvtools::Extension::kSPV_AMD_texture_gather_bias_lod}; +static const spvtools::Extension pygen_variable_exts_SPV_ARM_cooperative_matrix_layouts[] = {spvtools::Extension::kSPV_ARM_cooperative_matrix_layouts}; static const spvtools::Extension pygen_variable_exts_SPV_ARM_core_builtins[] = {spvtools::Extension::kSPV_ARM_core_builtins}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_demote_to_helper_invocation[] = {spvtools::Extension::kSPV_EXT_demote_to_helper_invocation}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_descriptor_indexing[] = {spvtools::Extension::kSPV_EXT_descriptor_indexing}; @@ -161,6 +164,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_KHR_ static const spvtools::Extension pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader[] = {spvtools::Extension::kSPV_EXT_mesh_shader, spvtools::Extension::kSPV_NV_mesh_shader}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_opacity_micromap[] = {spvtools::Extension::kSPV_EXT_opacity_micromap}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer[] = {spvtools::Extension::kSPV_EXT_physical_storage_buffer, spvtools::Extension::kSPV_KHR_physical_storage_buffer}; +static const spvtools::Extension pygen_variable_exts_SPV_EXT_replicated_composites[] = {spvtools::Extension::kSPV_EXT_replicated_composites}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float16_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float16_add}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_add[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_add}; static const spvtools::Extension pygen_variable_exts_SPV_EXT_shader_atomic_float_min_max[] = {spvtools::Extension::kSPV_EXT_shader_atomic_float_min_max}; @@ -200,6 +204,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_INTEL_kernel_attributes static const spvtools::Extension pygen_variable_exts_SPV_INTEL_long_composites[] = {spvtools::Extension::kSPV_INTEL_long_composites}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_loop_fuse[] = {spvtools::Extension::kSPV_INTEL_loop_fuse}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_masked_gather_scatter[] = {spvtools::Extension::kSPV_INTEL_masked_gather_scatter}; +static const spvtools::Extension pygen_variable_exts_SPV_INTEL_maximum_registers[] = {spvtools::Extension::kSPV_INTEL_maximum_registers}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_media_block_io[] = {spvtools::Extension::kSPV_INTEL_media_block_io}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_memory_access_aliasing[] = {spvtools::Extension::kSPV_INTEL_memory_access_aliasing}; static const spvtools::Extension pygen_variable_exts_SPV_INTEL_optnone[] = {spvtools::Extension::kSPV_INTEL_optnone}; @@ -255,6 +260,7 @@ static const spvtools::Extension pygen_variable_exts_SPV_NV_displacement_microma static const spvtools::Extension pygen_variable_exts_SPV_NV_geometry_shader_passthrough[] = {spvtools::Extension::kSPV_NV_geometry_shader_passthrough}; 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_raw_access_chains[] = {spvtools::Extension::kSPV_NV_raw_access_chains}; 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}; @@ -408,6 +414,12 @@ static const spv_operand_desc_t pygen_variable_FragmentShadingRateEntries[] = { {"Horizontal4Pixels", 0x0008, 1, pygen_variable_caps_FragmentShadingRateKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} }; +static const spv_operand_desc_t pygen_variable_RawAccessChainOperandsEntries[] = { + {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, + {"RobustnessPerComponentNV", 0x0001, 1, pygen_variable_caps_RawAccessChainsNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RobustnessPerElementNV", 0x0002, 1, pygen_variable_caps_RawAccessChainsNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + static const spv_operand_desc_t pygen_variable_SourceLanguageEntries[] = { {"Unknown", 0, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, {"ESSL", 1, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, @@ -434,18 +446,18 @@ static const spv_operand_desc_t pygen_variable_ExecutionModelEntries[] = { {"Kernel", 6, 1, pygen_variable_caps_Kernel, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1,0), 0xffffffffu}, {"TaskNV", 5267, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"MeshNV", 5268, 1, pygen_variable_caps_MeshShadingNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"RayGenerationKHR", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RayGenerationNV", 5313, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"IntersectionKHR", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"IntersectionNV", 5314, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"AnyHitKHR", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"AnyHitNV", 5315, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"ClosestHitKHR", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ClosestHitNV", 5316, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"MissKHR", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"MissNV", 5317, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"CallableKHR", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"CallableNV", 5318, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"TaskEXT", 5364, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"MeshEXT", 5365, 1, pygen_variable_caps_MeshShadingEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} }; @@ -530,14 +542,14 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { {"StencilRefLessBackAMD", 5084, 1, pygen_variable_caps_StencilExportEXT, 2, pygen_variable_exts_SPV_AMD_shader_early_and_late_fragment_testsSPV_EXT_shader_stencil_export, {}, 0xffffffffu, 0xffffffffu}, {"QuadDerivativesKHR", 5088, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"RequireFullQuadsKHR", 5089, 1, pygen_variable_caps_QuadControlKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"OutputLinesNV", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"OutputLinesEXT", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, - {"OutputPrimitivesNV", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"OutputLinesNV", 5269, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"OutputPrimitivesEXT", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"OutputPrimitivesNV", 5270, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"DerivativeGroupQuadsNV", 5289, 1, pygen_variable_caps_ComputeDerivativeGroupQuadsNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, {"DerivativeGroupLinearNV", 5290, 1, pygen_variable_caps_ComputeDerivativeGroupLinearNV, 1, pygen_variable_exts_SPV_NV_compute_shader_derivatives, {}, 0xffffffffu, 0xffffffffu}, - {"OutputTrianglesNV", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"OutputTrianglesEXT", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"OutputTrianglesNV", 5298, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PixelInterlockOrderedEXT", 5366, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, {"PixelInterlockUnorderedEXT", 5367, 1, pygen_variable_caps_FragmentShaderPixelInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, {"SampleInterlockOrderedEXT", 5368, 1, pygen_variable_caps_FragmentShaderSampleInterlockEXT, 1, pygen_variable_exts_SPV_EXT_fragment_shader_interlock, {}, 0xffffffffu, 0xffffffffu}, @@ -558,7 +570,10 @@ static const spv_operand_desc_t pygen_variable_ExecutionModeEntries[] = { {"FPFastMathDefault", 6028, 1, pygen_variable_caps_FloatControls2, 0, nullptr, {SPV_OPERAND_TYPE_ID, SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, {"StreamingInterfaceINTEL", 6154, 1, pygen_variable_caps_FPGAKernelAttributesINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, {"RegisterMapInterfaceINTEL", 6160, 1, pygen_variable_caps_FPGAKernelAttributesv2INTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, - {"NamedBarrierCountINTEL", 6417, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu} + {"NamedBarrierCountINTEL", 6417, 1, pygen_variable_caps_VectorComputeINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaximumRegistersINTEL", 6461, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, + {"MaximumRegistersIdINTEL", 6462, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_ID}, 0xffffffffu, 0xffffffffu}, + {"NamedMaximumRegistersINTEL", 6463, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { @@ -578,18 +593,18 @@ static const spv_operand_desc_t pygen_variable_StorageClassEntries[] = { {"TileImageEXT", 4172, 1, pygen_variable_caps_TileImageColorReadAccessEXT, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"NodePayloadAMDX", 5068, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"NodeOutputPayloadAMDX", 5076, 1, pygen_variable_caps_ShaderEnqueueAMDX, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"CallableDataKHR", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"CallableDataNV", 5328, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"IncomingCallableDataKHR", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingCallableDataNV", 5329, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"RayPayloadKHR", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayPayloadNV", 5338, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"HitAttributeKHR", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"HitAttributeNV", 5339, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"IncomingRayPayloadKHR", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"IncomingRayPayloadNV", 5342, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"ShaderRecordBufferKHR", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ShaderRecordBufferNV", 5343, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"PhysicalStorageBuffer", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"PhysicalStorageBufferEXT", 5349, 1, pygen_variable_caps_PhysicalStorageBufferAddresses, 2, pygen_variable_exts_SPV_EXT_physical_storage_bufferSPV_KHR_physical_storage_buffer, {}, SPV_SPIRV_VERSION_WORD(1,5), 0xffffffffu}, {"HitObjectAttributeNV", 5385, 1, pygen_variable_caps_ShaderInvocationReorderNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, @@ -841,8 +856,8 @@ static const spv_operand_desc_t pygen_variable_DecorationEntries[] = { {"PassthroughNV", 5250, 1, pygen_variable_caps_GeometryShaderPassthroughNV, 1, pygen_variable_exts_SPV_NV_geometry_shader_passthrough, {}, 0xffffffffu, 0xffffffffu}, {"ViewportRelativeNV", 5252, 1, pygen_variable_caps_ShaderViewportMaskNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"SecondaryViewportRelativeNV", 5256, 1, pygen_variable_caps_ShaderStereoViewNV, 1, pygen_variable_exts_SPV_NV_stereo_view_rendering, {SPV_OPERAND_TYPE_LITERAL_INTEGER}, 0xffffffffu, 0xffffffffu}, - {"PerPrimitiveNV", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PerPrimitiveEXT", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, + {"PerPrimitiveNV", 5271, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PerViewNV", 5272, 1, pygen_variable_caps_MeshShadingNV, 1, pygen_variable_exts_SPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PerTaskNV", 5273, 2, pygen_variable_caps_MeshShadingNVMeshShadingEXT, 2, pygen_variable_exts_SPV_EXT_mesh_shaderSPV_NV_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PerVertexKHR", 5285, 2, pygen_variable_caps_FragmentBarycentricNVFragmentBarycentricKHR, 2, pygen_variable_exts_SPV_KHR_fragment_shader_barycentricSPV_NV_fragment_shader_barycentric, {}, 0xffffffffu, 0xffffffffu}, @@ -1027,37 +1042,37 @@ static const spv_operand_desc_t pygen_variable_BuiltInEntries[] = { {"PrimitiveLineIndicesEXT", 5295, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"PrimitiveTriangleIndicesEXT", 5296, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, {"CullPrimitiveEXT", 5299, 1, pygen_variable_caps_MeshShadingEXT, 1, pygen_variable_exts_SPV_EXT_mesh_shader, {}, 0xffffffffu, 0xffffffffu}, - {"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"LaunchIdKHR", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchIdNV", 5319, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"LaunchSizeKHR", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"LaunchSizeNV", 5320, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"WorldRayOriginKHR", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayOriginNV", 5321, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"WorldRayDirectionKHR", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldRayDirectionNV", 5322, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"ObjectRayOriginKHR", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayOriginNV", 5323, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"ObjectRayDirectionKHR", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectRayDirectionNV", 5324, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"RayTminKHR", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTminNV", 5325, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"RayTmaxKHR", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"RayTmaxNV", 5326, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"InstanceCustomIndexKHR", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"InstanceCustomIndexNV", 5327, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"ObjectToWorldKHR", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, - {"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"ObjectToWorldNV", 5330, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"WorldToObjectKHR", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, + {"WorldToObjectNV", 5331, 2, pygen_variable_caps_RayTracingNVRayTracingKHR, 2, pygen_variable_exts_SPV_KHR_ray_tracingSPV_NV_ray_tracing, {}, 0xffffffffu, 0xffffffffu}, {"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}, + {"HitKindNV", 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}, {"HitTriangleVertexPositionsKHR", 5335, 1, pygen_variable_caps_RayTracingPositionFetchKHR, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"HitMicroTriangleVertexPositionsNV", 5337, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, {"HitMicroTriangleVertexBarycentricsNV", 5344, 1, pygen_variable_caps_RayTracingDisplacementMicromapNV, 0, nullptr, {}, 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}, + {"IncomingRayFlagsNV", 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}, {"WarpsPerSMNV", 5374, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, {"SMCountNV", 5375, 1, pygen_variable_caps_ShaderSMBuiltinsNV, 1, pygen_variable_exts_SPV_NV_shader_sm_builtins, {}, 0xffffffffu, 0xffffffffu}, @@ -1170,6 +1185,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"TileImageColorReadAccessEXT", 4166, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, {"TileImageDepthReadAccessEXT", 4167, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, {"TileImageStencilReadAccessEXT", 4168, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_shader_tile_image, {}, 0xffffffffu, 0xffffffffu}, + {"CooperativeMatrixLayoutsARM", 4201, 0, nullptr, 1, pygen_variable_exts_SPV_ARM_cooperative_matrix_layouts, {}, 0xffffffffu, 0xffffffffu}, {"FragmentShadingRateKHR", 4422, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_fragment_shading_rate, {}, 0xffffffffu, 0xffffffffu}, {"SubgroupBallotKHR", 4423, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_shader_ballot, {}, 0xffffffffu, 0xffffffffu}, {"DrawParameters", 4427, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_shader_draw_parameters, {}, SPV_SPIRV_VERSION_WORD(1,3), 0xffffffffu}, @@ -1280,6 +1296,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"RayQueryPositionFetchKHR", 5391, 1, pygen_variable_caps_Shader, 1, pygen_variable_exts_SPV_KHR_ray_tracing_position_fetch, {}, 0xffffffffu, 0xffffffffu}, {"AtomicFloat16VectorNV", 5404, 0, nullptr, 1, pygen_variable_exts_SPV_NV_shader_atomic_fp16_vector, {}, 0xffffffffu, 0xffffffffu}, {"RayTracingDisplacementMicromapNV", 5409, 1, pygen_variable_caps_RayTracingKHR, 1, pygen_variable_exts_SPV_NV_displacement_micromap, {}, 0xffffffffu, 0xffffffffu}, + {"RawAccessChainsNV", 5414, 0, nullptr, 1, pygen_variable_exts_SPV_NV_raw_access_chains, {}, 0xffffffffu, 0xffffffffu}, {"SubgroupShuffleINTEL", 5568, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, {"SubgroupBufferBlockIOINTEL", 5569, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, {"SubgroupImageBlockIOINTEL", 5570, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_subgroups, {}, 0xffffffffu, 0xffffffffu}, @@ -1332,6 +1349,7 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"DotProductKHR", 6019, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_integer_dot_product, {}, SPV_SPIRV_VERSION_WORD(1,6), 0xffffffffu}, {"RayCullMaskKHR", 6020, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_ray_cull_mask, {}, 0xffffffffu, 0xffffffffu}, {"CooperativeMatrixKHR", 6022, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_cooperative_matrix, {}, 0xffffffffu, 0xffffffffu}, + {"ReplicatedCompositesEXT", 6024, 0, nullptr, 1, pygen_variable_exts_SPV_EXT_replicated_composites, {}, 0xffffffffu, 0xffffffffu}, {"BitInstructions", 6025, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_bit_instructions, {}, 0xffffffffu, 0xffffffffu}, {"GroupNonUniformRotateKHR", 6026, 1, pygen_variable_caps_GroupNonUniform, 1, pygen_variable_exts_SPV_KHR_subgroup_rotate, {}, 0xffffffffu, 0xffffffffu}, {"FloatControls2", 6029, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_float_controls2, {}, 0xffffffffu, 0xffffffffu}, @@ -1352,7 +1370,8 @@ static const spv_operand_desc_t pygen_variable_CapabilityEntries[] = { {"GlobalVariableFPGADecorationsINTEL", 6189, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_global_variable_fpga_decorations, {}, 0xffffffffu, 0xffffffffu}, {"GroupUniformArithmeticKHR", 6400, 0, nullptr, 1, pygen_variable_exts_SPV_KHR_uniform_group_instructions, {}, 0xffffffffu, 0xffffffffu}, {"MaskedGatherScatterINTEL", 6427, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_masked_gather_scatter, {}, 0xffffffffu, 0xffffffffu}, - {"CacheControlsINTEL", 6441, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_cache_controls, {}, 0xffffffffu, 0xffffffffu} + {"CacheControlsINTEL", 6441, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_cache_controls, {}, 0xffffffffu, 0xffffffffu}, + {"RegisterLimitsINTEL", 6460, 0, nullptr, 1, pygen_variable_exts_SPV_INTEL_maximum_registers, {}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_RayQueryIntersectionEntries[] = { @@ -1387,7 +1406,9 @@ static const spv_operand_desc_t pygen_variable_CooperativeMatrixOperandsEntries[ static const spv_operand_desc_t pygen_variable_CooperativeMatrixLayoutEntries[] = { {"RowMajorKHR", 0, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, - {"ColumnMajorKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} + {"ColumnMajorKHR", 1, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"RowBlockedInterleavedARM", 4202, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu}, + {"ColumnBlockedInterleavedARM", 4203, 0, nullptr, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} }; static const spv_operand_desc_t pygen_variable_CooperativeMatrixUseEntries[] = { @@ -1416,6 +1437,10 @@ static const spv_operand_desc_t pygen_variable_StoreCacheControlEntries[] = { {"StreamingINTEL", 3, 1, pygen_variable_caps_CacheControlsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} }; +static const spv_operand_desc_t pygen_variable_NamedMaximumNumberOfRegistersEntries[] = { + {"AutoINTEL", 0, 1, pygen_variable_caps_RegisterLimitsINTEL, 0, nullptr, {}, 0xffffffffu, 0xffffffffu} +}; + static const spv_operand_desc_t pygen_variable_DebugInfoFlagsEntries[] = { {"None", 0x0000, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, {"FlagIsProtected", 0x01, 0, nullptr, 0, nullptr, {}, SPV_SPIRV_VERSION_WORD(1, 0), 0xffffffffu}, @@ -1545,6 +1570,7 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { {SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO, ARRAY_SIZE(pygen_variable_KernelProfilingInfoEntries), pygen_variable_KernelProfilingInfoEntries}, {SPV_OPERAND_TYPE_RAY_FLAGS, ARRAY_SIZE(pygen_variable_RayFlagsEntries), pygen_variable_RayFlagsEntries}, {SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE, ARRAY_SIZE(pygen_variable_FragmentShadingRateEntries), pygen_variable_FragmentShadingRateEntries}, + {SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, ARRAY_SIZE(pygen_variable_RawAccessChainOperandsEntries), pygen_variable_RawAccessChainOperandsEntries}, {SPV_OPERAND_TYPE_SOURCE_LANGUAGE, ARRAY_SIZE(pygen_variable_SourceLanguageEntries), pygen_variable_SourceLanguageEntries}, {SPV_OPERAND_TYPE_EXECUTION_MODEL, ARRAY_SIZE(pygen_variable_ExecutionModelEntries), pygen_variable_ExecutionModelEntries}, {SPV_OPERAND_TYPE_ADDRESSING_MODEL, ARRAY_SIZE(pygen_variable_AddressingModelEntries), pygen_variable_AddressingModelEntries}, @@ -1582,6 +1608,7 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { {SPV_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, ARRAY_SIZE(pygen_variable_InitializationModeQualifierEntries), pygen_variable_InitializationModeQualifierEntries}, {SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_LoadCacheControlEntries), pygen_variable_LoadCacheControlEntries}, {SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, ARRAY_SIZE(pygen_variable_StoreCacheControlEntries), pygen_variable_StoreCacheControlEntries}, + {SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, ARRAY_SIZE(pygen_variable_NamedMaximumNumberOfRegistersEntries), pygen_variable_NamedMaximumNumberOfRegistersEntries}, {SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS, ARRAY_SIZE(pygen_variable_DebugInfoFlagsEntries), pygen_variable_DebugInfoFlagsEntries}, {SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING, ARRAY_SIZE(pygen_variable_DebugBaseTypeAttributeEncodingEntries), pygen_variable_DebugBaseTypeAttributeEncodingEntries}, {SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE, ARRAY_SIZE(pygen_variable_DebugCompositeTypeEntries), pygen_variable_DebugCompositeTypeEntries}, @@ -1595,6 +1622,7 @@ static const spv_operand_desc_group_t pygen_variable_OperandInfoTable[] = { {SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY, ARRAY_SIZE(pygen_variable_CLDEBUG100_DebugImportedEntityEntries), pygen_variable_CLDEBUG100_DebugImportedEntityEntries}, {SPV_OPERAND_TYPE_OPTIONAL_IMAGE, ARRAY_SIZE(pygen_variable_ImageOperandsEntries), pygen_variable_ImageOperandsEntries}, {SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS, ARRAY_SIZE(pygen_variable_MemoryAccessEntries), pygen_variable_MemoryAccessEntries}, + {SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS, ARRAY_SIZE(pygen_variable_RawAccessChainOperandsEntries), pygen_variable_RawAccessChainOperandsEntries}, {SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER, ARRAY_SIZE(pygen_variable_AccessQualifierEntries), pygen_variable_AccessQualifierEntries}, {SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT, ARRAY_SIZE(pygen_variable_PackedVectorFormatEntries), pygen_variable_PackedVectorFormatEntries}, {SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS, ARRAY_SIZE(pygen_variable_CooperativeMatrixOperandsEntries), pygen_variable_CooperativeMatrixOperandsEntries} diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp index 0a6e630..d72a5d8 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/instrument.hpp @@ -22,8 +22,6 @@ // This file provides an external interface for applications that wish to // communicate with shaders instrumented by passes created by: // -// CreateInstBindlessCheckPass -// CreateInstBuffAddrCheckPass // CreateInstDebugPrintfPass // // More detailed documentation of these routines can be found in optimizer.hpp @@ -34,17 +32,12 @@ namespace spvtools { // // The following values provide offsets into the output buffer struct // generated by InstrumentPass::GenDebugStreamWrite. This method is utilized -// by InstBindlessCheckPass, InstBuffAddrCheckPass, and InstDebugPrintfPass. +// by InstDebugPrintfPass. // // The 1st member of the debug output buffer contains a set of flags // controlling the behavior of instrumentation code. static const int kDebugOutputFlagsOffset = 0; -// Values stored at kDebugOutputFlagsOffset -enum kInstFlags : unsigned int { - kInstBufferOOBEnable = 0x1, -}; - // The 2nd member of the debug output buffer contains the next available word // in the data stream to be written. Shaders will atomically read and update // this value so as not to overwrite each others records. This value must be diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h index 20426cc..3bd4494 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.h @@ -33,15 +33,19 @@ extern "C" { #else #define SPIRV_TOOLS_EXPORT __declspec(dllimport) #endif +#define SPIRV_TOOLS_LOCAL #else #if defined(SPIRV_TOOLS_IMPLEMENTATION) #define SPIRV_TOOLS_EXPORT __attribute__((visibility("default"))) +#define SPIRV_TOOLS_LOCAL __attribute__((visibility("hidden"))) #else #define SPIRV_TOOLS_EXPORT +#define SPIRV_TOOLS_LOCAL #endif #endif #else #define SPIRV_TOOLS_EXPORT +#define SPIRV_TOOLS_LOCAL #endif // Helpers @@ -302,6 +306,12 @@ typedef enum spv_operand_type_t { SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL, // Enum type from SPV_INTEL_cache_controls SPV_OPERAND_TYPE_STORE_CACHE_CONTROL, + // Enum type from SPV_INTEL_maximum_registers + SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, + // Enum type from SPV_NV_raw_access_chains + SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, + // Optional enum type from SPV_NV_raw_access_chains + SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS, // This is a sentinel value, and does not represent an operand type. // It should come last. @@ -328,6 +338,7 @@ typedef enum spv_ext_inst_type_t { SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100, SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100, + SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION, // Multiple distinct extended instruction set types could return this // value, if they are prefixed with NonSemantic. and are otherwise diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp index ee6c846..59ff82b 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/libspirv.hpp @@ -37,7 +37,7 @@ using InstructionParser = std::function; // C++ RAII wrapper around the C context object spv_context. -class Context { +class SPIRV_TOOLS_EXPORT Context { public: // Constructs a context targeting the given environment |env|. // @@ -73,7 +73,7 @@ class Context { }; // A RAII wrapper around a validator options object. -class ValidatorOptions { +class SPIRV_TOOLS_EXPORT ValidatorOptions { public: ValidatorOptions() : options_(spvValidatorOptionsCreate()) {} ~ValidatorOptions() { spvValidatorOptionsDestroy(options_); } @@ -163,7 +163,7 @@ class ValidatorOptions { }; // A C++ wrapper around an optimization options object. -class OptimizerOptions { +class SPIRV_TOOLS_EXPORT OptimizerOptions { public: OptimizerOptions() : options_(spvOptimizerOptionsCreate()) {} ~OptimizerOptions() { spvOptimizerOptionsDestroy(options_); } @@ -205,7 +205,7 @@ class OptimizerOptions { }; // A C++ wrapper around a reducer options object. -class ReducerOptions { +class SPIRV_TOOLS_EXPORT ReducerOptions { public: ReducerOptions() : options_(spvReducerOptionsCreate()) {} ~ReducerOptions() { spvReducerOptionsDestroy(options_); } @@ -236,7 +236,7 @@ class ReducerOptions { }; // A C++ wrapper around a fuzzer options object. -class FuzzerOptions { +class SPIRV_TOOLS_EXPORT FuzzerOptions { public: FuzzerOptions() : options_(spvFuzzerOptionsCreate()) {} ~FuzzerOptions() { spvFuzzerOptionsDestroy(options_); } @@ -283,7 +283,7 @@ class FuzzerOptions { // provides methods for assembling, disassembling, and validating. // // Instances of this class provide basic thread-safety guarantee. -class SpirvTools { +class SPIRV_TOOLS_EXPORT SpirvTools { public: enum { // Default assembling option used by assemble(): @@ -388,7 +388,8 @@ class SpirvTools { bool IsValid() const; private: - struct Impl; // Opaque struct for holding the data fields used by this class. + struct SPIRV_TOOLS_LOCAL + Impl; // Opaque struct for holding the data fields used by this class. std::unique_ptr impl_; // Unique pointer to implementation data. }; diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linker.hpp b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linker.hpp index 5b60cb9..6ba6e96 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linker.hpp +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linker.hpp @@ -24,7 +24,7 @@ namespace spvtools { -class LinkerOptions { +class SPIRV_TOOLS_EXPORT LinkerOptions { public: // Returns whether a library or an executable should be produced by the // linking phase. @@ -84,14 +84,15 @@ class LinkerOptions { // * Some entry points were defined multiple times; // * Some imported symbols did not have an exported counterpart; // * Possibly other reasons. -spv_result_t Link(const Context& context, - const std::vector>& binaries, - std::vector* linked_binary, - const LinkerOptions& options = LinkerOptions()); -spv_result_t Link(const Context& context, const uint32_t* const* binaries, - const size_t* binary_sizes, size_t num_binaries, - std::vector* linked_binary, - const LinkerOptions& options = LinkerOptions()); +SPIRV_TOOLS_EXPORT spv_result_t +Link(const Context& context, const std::vector>& binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); +SPIRV_TOOLS_EXPORT spv_result_t +Link(const Context& context, const uint32_t* const* binaries, + const size_t* binary_sizes, size_t num_binaries, + std::vector* linked_binary, + const LinkerOptions& options = LinkerOptions()); } // namespace spvtools diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp index 52ed5a4..ccbcf0c 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/linter.hpp @@ -24,7 +24,7 @@ namespace spvtools { // provides a method for linting. // // Instances of this class provides basic thread-safety guarantee. -class Linter { +class SPIRV_TOOLS_EXPORT Linter { public: explicit Linter(spv_target_env env); @@ -40,7 +40,7 @@ class Linter { bool Run(const uint32_t* binary, size_t binary_size); private: - struct Impl; + struct SPIRV_TOOLS_LOCAL Impl; std::unique_ptr impl_; }; } // namespace spvtools diff --git a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp index 926e438..216e68a 100644 --- a/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp +++ b/libs/bgfx/3rdparty/spirv-tools/include/spirv-tools/optimizer.hpp @@ -37,14 +37,14 @@ struct DescriptorSetAndBinding; // provides methods for registering optimization passes and optimizing. // // Instances of this class provides basic thread-safety guarantee. -class Optimizer { +class SPIRV_TOOLS_EXPORT Optimizer { public: // The token for an optimization pass. It is returned via one of the // Create*Pass() standalone functions at the end of this header file and // consumed by the RegisterPass() method. Tokens are one-time objects that // only support move; copying is not allowed. struct PassToken { - struct Impl; // Opaque struct for holding internal data. + struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data. PassToken(std::unique_ptr); @@ -239,7 +239,7 @@ class Optimizer { Optimizer& SetValidateAfterAll(bool validate); private: - struct Impl; // Opaque struct for holding internal data. + struct SPIRV_TOOLS_LOCAL Impl; // Opaque struct for holding internal data. std::unique_ptr impl_; // Unique pointer to internal data. }; @@ -747,53 +747,6 @@ Optimizer::PassToken CreateReduceLoadSizePass( // them into a single instruction where possible. Optimizer::PassToken CreateCombineAccessChainsPass(); -// Create a pass to instrument bindless descriptor checking -// This pass instruments all bindless references to check that descriptor -// array indices are inbounds, and if the descriptor indexing extension is -// enabled, that the descriptor has been initialized. If the reference is -// invalid, a record is written to the debug output buffer (if space allows) -// and a null value is returned. This pass is designed to support bindless -// validation in the Vulkan validation layers. -// -// TODO(greg-lunarg): Add support for buffer references. Currently only does -// checking for image references. -// -// Dead code elimination should be run after this pass as the original, -// potentially invalid code is not removed and could cause undefined behavior, -// including crashes. It may also be beneficial to run Simplification -// (ie Constant Propagation), DeadBranchElim and BlockMerge after this pass to -// optimize instrument code involving the testing of compile-time constants. -// It is also generally recommended that this pass (and all -// instrumentation passes) be run after any legalization and optimization -// passes. This will give better analysis for the instrumentation and avoid -// potentially de-optimizing the instrument code, for example, inlining -// the debug record output function throughout the module. -// -// The instrumentation will write |shader_id| in each output record -// to identify the shader module which generated the record. -Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id); - -// Create a pass to instrument physical buffer address checking -// This pass instruments all physical buffer address references to check that -// all referenced bytes fall in a valid buffer. If the reference is -// invalid, a record is written to the debug output buffer (if space allows) -// and a null value is returned. This pass is designed to support buffer -// address validation in the Vulkan validation layers. -// -// Dead code elimination should be run after this pass as the original, -// potentially invalid code is not removed and could cause undefined behavior, -// including crashes. Instruction simplification would likely also be -// beneficial. It is also generally recommended that this pass (and all -// instrumentation passes) be run after any legalization and optimization -// passes. This will give better analysis for the instrumentation and avoid -// potentially de-optimizing the instrument code, for example, inlining -// the debug record output function throughout the module. -// -// The instrumentation will read and write buffers in debug -// descriptor set |desc_set|. It will write |shader_id| in each output record -// to identify the shader module which generated the record. -Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id); - // Create a pass to instrument OpDebugPrintf instructions. // This pass replaces all OpDebugPrintf instructions with instructions to write // a record containing the string id and the all specified values into a special @@ -903,6 +856,12 @@ Optimizer::PassToken CreateAmdExtToKhrPass(); // propagated into their final positions. Optimizer::PassToken CreateInterpolateFixupPass(); +// Replace OpExtInst instructions with OpExtInstWithForwardRefsKHR when +// the instruction contains a forward reference to another debug instuction. +// Replace OpExtInstWithForwardRefsKHR with OpExtInst when there are no forward +// reference to another debug instruction. +Optimizer::PassToken CreateOpExtInstWithForwardReferenceFixupPass(); + // Removes unused components from composite input variables. Current // implementation just removes trailing unused components from input arrays // and structs. The pass performs best after maximizing dead code removal. diff --git a/libs/bgfx/3rdparty/spirv-tools/source/binary.cpp b/libs/bgfx/3rdparty/spirv-tools/source/binary.cpp index 3cfdee0..a39bcf0 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/binary.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/binary.cpp @@ -473,7 +473,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0"; parsed_operand.type = SPV_OPERAND_TYPE_ID; - if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) { + if (spvIsExtendedInstruction(opcode) && parsed_operand.offset == 3) { // The current word is the extended instruction set Id. // Set the extended instruction set type for the current instruction. auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word); @@ -494,7 +494,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, break; case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { - assert(spv::Op::OpExtInst == opcode); + assert(spvIsExtendedInstruction(opcode)); assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE); spv_ext_inst_desc ext_inst; if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) == @@ -670,7 +670,8 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_QUANTIZATION_MODES: case SPV_OPERAND_TYPE_OVERFLOW_MODES: case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT: - case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: { + case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: + case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: { // A single word that is a plain enum value. // Map an optional operand type to its corresponding concrete type. @@ -710,6 +711,7 @@ spv_result_t Parser::parseOperand(size_t inst_offset, case SPV_OPERAND_TYPE_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: @@ -720,10 +722,12 @@ spv_result_t Parser::parseOperand(size_t inst_offset, // Map an optional operand type to its corresponding concrete type. if (type == SPV_OPERAND_TYPE_OPTIONAL_IMAGE) parsed_operand.type = SPV_OPERAND_TYPE_IMAGE; - else if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS) + if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS) parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS; if (type == SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS) parsed_operand.type = SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS; + if (type == SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS) + parsed_operand.type = SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS; // Check validity of set mask bits. Also prepare for operands for those // masks if they have any. To get operand order correct, scan from diff --git a/libs/bgfx/3rdparty/spirv-tools/source/disassemble.cpp b/libs/bgfx/3rdparty/spirv-tools/source/disassemble.cpp index 5173fbf..8fc4ee2 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/disassemble.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/disassemble.cpp @@ -194,7 +194,27 @@ spv_result_t DisassembleTargetInstruction( return SPV_SUCCESS; } +uint32_t GetLineLengthWithoutColor(const std::string line) { + // Currently, every added color is in the form \x1b...m, so instead of doing a + // lot of string comparisons with spvtools::clr::* strings, we just ignore + // those ranges. + uint32_t length = 0; + for (size_t i = 0; i < line.size(); ++i) { + if (line[i] == '\x1b') { + do { + ++i; + } while (line[i] != 'm'); + continue; + } + + ++length; + } + + return length; +} + constexpr int kStandardIndent = 15; +constexpr uint32_t kCommentColumn = 50; } // namespace namespace disassemble { @@ -212,7 +232,8 @@ InstructionDisassembler::InstructionDisassembler(const AssemblyGrammar& grammar, comment_(spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_COMMENT, options)), show_byte_offset_( spvIsInBitfield(SPV_BINARY_TO_TEXT_OPTION_SHOW_BYTE_OFFSET, options)), - name_mapper_(std::move(name_mapper)) {} + name_mapper_(std::move(name_mapper)), + last_instruction_comment_alignment_(0) {} void InstructionDisassembler::EmitHeaderSpirv() { stream_ << "; SPIR-V\n"; } @@ -246,47 +267,119 @@ void InstructionDisassembler::EmitInstruction( const spv_parsed_instruction_t& inst, size_t inst_byte_offset) { auto opcode = static_cast(inst.opcode); + // To better align the comments (if any), write the instruction to a line + // first so its length can be readily available. + std::ostringstream line; + if (inst.result_id) { SetBlue(); const std::string id_name = name_mapper_(inst.result_id); if (indent_) - stream_ << std::setw(std::max(0, indent_ - 3 - int(id_name.size()))); - stream_ << "%" << id_name; + line << std::setw(std::max(0, indent_ - 3 - int(id_name.size()))); + line << "%" << id_name; ResetColor(); - stream_ << " = "; + line << " = "; } else { - stream_ << std::string(indent_, ' '); + line << std::string(indent_, ' '); } - stream_ << "Op" << spvOpcodeString(opcode); + line << "Op" << spvOpcodeString(opcode); for (uint16_t i = 0; i < inst.num_operands; i++) { const spv_operand_type_t type = inst.operands[i].type; assert(type != SPV_OPERAND_TYPE_NONE); if (type == SPV_OPERAND_TYPE_RESULT_ID) continue; - stream_ << " "; - EmitOperand(inst, i); + line << " "; + EmitOperand(line, inst, i); + } + + // For the sake of comment generation, store information from some + // instructions for the future. + if (comment_) { + GenerateCommentForDecoratedId(inst); + } + + std::ostringstream comments; + const char* comment_separator = ""; + + if (show_byte_offset_) { + SetGrey(comments); + auto saved_flags = comments.flags(); + auto saved_fill = comments.fill(); + comments << comment_separator << "0x" << std::setw(8) << std::hex + << std::setfill('0') << inst_byte_offset; + comments.flags(saved_flags); + comments.fill(saved_fill); + ResetColor(comments); + comment_separator = ", "; } if (comment_ && opcode == spv::Op::OpName) { const spv_parsed_operand_t& operand = inst.operands[0]; const uint32_t word = inst.words[operand.offset]; - stream_ << " ; id %" << word; + comments << comment_separator << "id %" << word; + comment_separator = ", "; } - if (show_byte_offset_) { - SetGrey(); - auto saved_flags = stream_.flags(); - auto saved_fill = stream_.fill(); - stream_ << " ; 0x" << std::setw(8) << std::hex << std::setfill('0') - << inst_byte_offset; - stream_.flags(saved_flags); - stream_.fill(saved_fill); - ResetColor(); + if (comment_ && inst.result_id && id_comments_.count(inst.result_id) > 0) { + comments << comment_separator << id_comments_[inst.result_id].str(); + comment_separator = ", "; } + + stream_ << line.str(); + + if (!comments.str().empty()) { + // Align the comments + const uint32_t line_length = GetLineLengthWithoutColor(line.str()); + uint32_t align = std::max( + {line_length + 2, last_instruction_comment_alignment_, kCommentColumn}); + // Round up the alignment to a multiple of 4 for more niceness. + align = (align + 3) & ~0x3u; + last_instruction_comment_alignment_ = align; + + stream_ << std::string(align - line_length, ' ') << "; " << comments.str(); + } else { + last_instruction_comment_alignment_ = 0; + } + stream_ << "\n"; } +void InstructionDisassembler::GenerateCommentForDecoratedId( + const spv_parsed_instruction_t& inst) { + assert(comment_); + auto opcode = static_cast(inst.opcode); + + std::ostringstream partial; + uint32_t id = 0; + const char* separator = ""; + + switch (opcode) { + case spv::Op::OpDecorate: + // Take everything after `OpDecorate %id` and associate it with id. + id = inst.words[inst.operands[0].offset]; + for (uint16_t i = 1; i < inst.num_operands; i++) { + partial << separator; + separator = " "; + EmitOperand(partial, inst, i); + } + break; + default: + break; + } + + if (id == 0) { + return; + } + + // Add the new comment to the comments of this id + std::ostringstream& id_comment = id_comments_[id]; + if (!id_comment.str().empty()) { + id_comment << ", "; + } + id_comment << partial.str(); +} + void InstructionDisassembler::EmitSectionComment( const spv_parsed_instruction_t& inst, bool& inserted_decoration_space, bool& inserted_debug_space, bool& inserted_type_space) { @@ -316,36 +409,37 @@ void InstructionDisassembler::EmitSectionComment( } } -void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, - const uint16_t operand_index) { +void InstructionDisassembler::EmitOperand(std::ostream& stream, + const spv_parsed_instruction_t& inst, + const uint16_t operand_index) const { assert(operand_index < inst.num_operands); const spv_parsed_operand_t& operand = inst.operands[operand_index]; const uint32_t word = inst.words[operand.offset]; switch (operand.type) { case SPV_OPERAND_TYPE_RESULT_ID: assert(false && " is not supposed to be handled here"); - SetBlue(); - stream_ << "%" << name_mapper_(word); + SetBlue(stream); + stream << "%" << name_mapper_(word); break; case SPV_OPERAND_TYPE_ID: case SPV_OPERAND_TYPE_TYPE_ID: case SPV_OPERAND_TYPE_SCOPE_ID: case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID: - SetYellow(); - stream_ << "%" << name_mapper_(word); + SetYellow(stream); + stream << "%" << name_mapper_(word); break; case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: { spv_ext_inst_desc ext_inst; - SetRed(); + SetRed(stream); if (grammar_.lookupExtInst(inst.ext_inst_type, word, &ext_inst) == SPV_SUCCESS) { - stream_ << ext_inst->name; + stream << ext_inst->name; } else { if (!spvExtInstIsNonSemantic(inst.ext_inst_type)) { assert(false && "should have caught this earlier"); } else { // for non-semantic instruction sets we can just print the number - stream_ << word; + stream << word; } } } break; @@ -353,27 +447,27 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, spv_opcode_desc opcode_desc; if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc)) assert(false && "should have caught this earlier"); - SetRed(); - stream_ << opcode_desc->name; + SetRed(stream); + stream << opcode_desc->name; } break; case SPV_OPERAND_TYPE_LITERAL_INTEGER: case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: case SPV_OPERAND_TYPE_LITERAL_FLOAT: { - SetRed(); - EmitNumericLiteral(&stream_, inst, operand); - ResetColor(); + SetRed(stream); + EmitNumericLiteral(&stream, inst, operand); + ResetColor(stream); } break; case SPV_OPERAND_TYPE_LITERAL_STRING: { - stream_ << "\""; - SetGreen(); + stream << "\""; + SetGreen(stream); std::string str = spvDecodeLiteralStringOperand(inst, operand_index); for (char const& c : str) { - if (c == '"' || c == '\\') stream_ << '\\'; - stream_ << c; + if (c == '"' || c == '\\') stream << '\\'; + stream << c; } - ResetColor(); - stream_ << '"'; + ResetColor(stream); + stream << '"'; } break; case SPV_OPERAND_TYPE_CAPABILITY: case SPV_OPERAND_TYPE_SOURCE_LANGUAGE: @@ -415,7 +509,7 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, spv_operand_desc entry; if (grammar_.lookupOperand(operand.type, word, &entry)) assert(false && "should have caught this earlier"); - stream_ << entry->name; + stream << entry->name; } break; case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE: case SPV_OPERAND_TYPE_FUNCTION_CONTROL: @@ -425,26 +519,28 @@ void InstructionDisassembler::EmitOperand(const spv_parsed_instruction_t& inst, case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: - EmitMaskOperand(operand.type, word); + case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS: + EmitMaskOperand(stream, operand.type, word); break; default: if (spvOperandIsConcreteMask(operand.type)) { - EmitMaskOperand(operand.type, word); + EmitMaskOperand(stream, operand.type, word); } else if (spvOperandIsConcrete(operand.type)) { spv_operand_desc entry; if (grammar_.lookupOperand(operand.type, word, &entry)) assert(false && "should have caught this earlier"); - stream_ << entry->name; + stream << entry->name; } else { assert(false && "unhandled or invalid case"); } break; } - ResetColor(); + ResetColor(stream); } -void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type, - const uint32_t word) { +void InstructionDisassembler::EmitMaskOperand(std::ostream& stream, + const spv_operand_type_t type, + const uint32_t word) const { // Scan the mask from least significant bit to most significant bit. For each // set bit, emit the name of that bit. Separate multiple names with '|'. uint32_t remaining_word = word; @@ -456,8 +552,8 @@ void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type, spv_operand_desc entry; if (grammar_.lookupOperand(type, mask, &entry)) assert(false && "should have caught this earlier"); - if (num_emitted) stream_ << "|"; - stream_ << entry->name; + if (num_emitted) stream << "|"; + stream << entry->name; num_emitted++; } } @@ -466,28 +562,35 @@ void InstructionDisassembler::EmitMaskOperand(const spv_operand_type_t type, // of the 0 value. In many cases, that's "None". spv_operand_desc entry; if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry)) - stream_ << entry->name; + stream << entry->name; } } -void InstructionDisassembler::ResetColor() { - if (color_) stream_ << spvtools::clr::reset{print_}; +void InstructionDisassembler::ResetColor(std::ostream& stream) const { + if (color_) stream << spvtools::clr::reset{print_}; } -void InstructionDisassembler::SetGrey() { - if (color_) stream_ << spvtools::clr::grey{print_}; +void InstructionDisassembler::SetGrey(std::ostream& stream) const { + if (color_) stream << spvtools::clr::grey{print_}; } -void InstructionDisassembler::SetBlue() { - if (color_) stream_ << spvtools::clr::blue{print_}; +void InstructionDisassembler::SetBlue(std::ostream& stream) const { + if (color_) stream << spvtools::clr::blue{print_}; } -void InstructionDisassembler::SetYellow() { - if (color_) stream_ << spvtools::clr::yellow{print_}; +void InstructionDisassembler::SetYellow(std::ostream& stream) const { + if (color_) stream << spvtools::clr::yellow{print_}; } -void InstructionDisassembler::SetRed() { - if (color_) stream_ << spvtools::clr::red{print_}; +void InstructionDisassembler::SetRed(std::ostream& stream) const { + if (color_) stream << spvtools::clr::red{print_}; } -void InstructionDisassembler::SetGreen() { - if (color_) stream_ << spvtools::clr::green{print_}; +void InstructionDisassembler::SetGreen(std::ostream& stream) const { + if (color_) stream << spvtools::clr::green{print_}; } + +void InstructionDisassembler::ResetColor() { ResetColor(stream_); } +void InstructionDisassembler::SetGrey() { SetGrey(stream_); } +void InstructionDisassembler::SetBlue() { SetBlue(stream_); } +void InstructionDisassembler::SetYellow() { SetYellow(stream_); } +void InstructionDisassembler::SetRed() { SetRed(stream_); } +void InstructionDisassembler::SetGreen() { SetGreen(stream_); } } // namespace disassemble std::string spvInstructionBinaryToText(const spv_target_env env, diff --git a/libs/bgfx/3rdparty/spirv-tools/source/disassemble.h b/libs/bgfx/3rdparty/spirv-tools/source/disassemble.h index b520a1e..0dab3c5 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/disassemble.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/disassemble.h @@ -16,6 +16,7 @@ #define SOURCE_DISASSEMBLE_H_ #include +#include #include #include "source/name_mapper.h" @@ -74,13 +75,25 @@ class InstructionDisassembler { void SetGreen(); private: + void ResetColor(std::ostream& stream) const; + void SetGrey(std::ostream& stream) const; + void SetBlue(std::ostream& stream) const; + void SetYellow(std::ostream& stream) const; + void SetRed(std::ostream& stream) const; + void SetGreen(std::ostream& stream) const; + // Emits an operand for the given instruction, where the instruction // is at offset words from the start of the binary. - void EmitOperand(const spv_parsed_instruction_t& inst, - const uint16_t operand_index); + void EmitOperand(std::ostream& stream, const spv_parsed_instruction_t& inst, + const uint16_t operand_index) const; // Emits a mask expression for the given mask word of the specified type. - void EmitMaskOperand(const spv_operand_type_t type, const uint32_t word); + void EmitMaskOperand(std::ostream& stream, const spv_operand_type_t type, + const uint32_t word) const; + + // Generate part of the instruction as a comment to be added to + // |id_comments_|. + void GenerateCommentForDecoratedId(const spv_parsed_instruction_t& inst); const spvtools::AssemblyGrammar& grammar_; std::ostream& stream_; @@ -90,6 +103,13 @@ class InstructionDisassembler { const int comment_; // Should we comment the source const bool show_byte_offset_; // Should we print byte offset, in hex? spvtools::NameMapper name_mapper_; + + // Some comments are generated as instructions (such as OpDecorate) are + // visited so that when the instruction with that result id is visited, the + // comment can be output. + std::unordered_map id_comments_; + // Align the comments in consecutive lines for more readability. + uint32_t last_instruction_comment_alignment_; }; } // namespace disassemble diff --git a/libs/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp b/libs/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp index 4e27954..9a5ba84 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/ext_inst.cpp @@ -30,6 +30,7 @@ #include "glsl.std.450.insts.inc" #include "nonsemantic.clspvreflection.insts.inc" #include "nonsemantic.shader.debuginfo.100.insts.inc" +#include "nonsemantic.vkspreflection.insts.inc" #include "opencl.debuginfo.100.insts.inc" #include "opencl.std.insts.inc" @@ -62,6 +63,9 @@ static const spv_ext_inst_group_t kGroups_1_0[] = { {SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION, ARRAY_SIZE(nonsemantic_clspvreflection_entries), nonsemantic_clspvreflection_entries}, + {SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION, + ARRAY_SIZE(nonsemantic_vkspreflection_entries), + nonsemantic_vkspreflection_entries}, }; static const spv_ext_inst_table_t kTable_1_0 = {ARRAY_SIZE(kGroups_1_0), @@ -138,6 +142,9 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) { if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) { return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION; } + if (!strncmp("NonSemantic.VkspReflection.", name, 27)) { + return SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION; + } // ensure to add any known non-semantic extended instruction sets // above this point, and update spvExtInstIsNonSemantic() if (!strncmp("NonSemantic.", name, 12)) { @@ -149,7 +156,8 @@ spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) { bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) { if (type == SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN || type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 || - type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) { + type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION || + type == SPV_EXT_INST_TYPE_NONSEMANTIC_VKSPREFLECTION) { return true; } return false; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opcode.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opcode.cpp index 38d1a1b..5076bbd 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opcode.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opcode.cpp @@ -225,6 +225,7 @@ int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) { case spv::Op::OpSpecConstantFalse: case spv::Op::OpSpecConstant: case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantCompositeReplicateEXT: case spv::Op::OpSpecConstantOp: return true; default: @@ -238,6 +239,7 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) { case spv::Op::OpConstantFalse: case spv::Op::OpConstant: case spv::Op::OpConstantComposite: + case spv::Op::OpConstantCompositeReplicateEXT: case spv::Op::OpConstantSampler: case spv::Op::OpConstantNull: case spv::Op::OpConstantFunctionPointerINTEL: @@ -245,6 +247,7 @@ int32_t spvOpcodeIsConstant(const spv::Op opcode) { case spv::Op::OpSpecConstantFalse: case spv::Op::OpSpecConstant: case spv::Op::OpSpecConstantComposite: + case spv::Op::OpSpecConstantCompositeReplicateEXT: case spv::Op::OpSpecConstantOp: return true; default: @@ -295,6 +298,7 @@ bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) { case spv::Op::OpPtrAccessChain: case spv::Op::OpLoad: case spv::Op::OpConstantNull: + case spv::Op::OpRawAccessChainNV: return true; default: return false; @@ -309,6 +313,7 @@ int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) { case spv::Op::OpFunctionParameter: case spv::Op::OpImageTexelPointer: case spv::Op::OpCopyObject: + case spv::Op::OpRawAccessChainNV: return true; default: return false; @@ -715,6 +720,16 @@ bool spvOpcodeIsImageSample(const spv::Op opcode) { } } +bool spvIsExtendedInstruction(const spv::Op opcode) { + switch (opcode) { + case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: + return true; + default: + return false; + } +} + std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) { switch (opcode) { case spv::Op::OpMemoryBarrier: @@ -754,6 +769,7 @@ bool spvOpcodeIsAccessChain(spv::Op opcode) { case spv::Op::OpInBoundsAccessChain: case spv::Op::OpPtrAccessChain: case spv::Op::OpInBoundsPtrAccessChain: + case spv::Op::OpRawAccessChainNV: return true; default: return false; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opcode.h b/libs/bgfx/3rdparty/spirv-tools/source/opcode.h index 217aeb2..cecd566 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opcode.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opcode.h @@ -146,6 +146,9 @@ bool spvOpcodeIsLinearAlgebra(spv::Op opcode); // Returns true for opcodes that represent image sample instructions. bool spvOpcodeIsImageSample(spv::Op opcode); +// Returns true if the opcode is either OpExtInst or OpExtInstWithForwardRefsKHR +bool spvIsExtendedInstruction(spv::Op opcode); + // Returns a vector containing the indices of the memory semantics // operands for |opcode|. std::vector spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/operand.cpp b/libs/bgfx/3rdparty/spirv-tools/source/operand.cpp index 6577f8f..e150045 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/operand.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/operand.cpp @@ -220,6 +220,11 @@ const char* spvOperandTypeStr(spv_operand_type_t type) { return "load cache control"; case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: return "store cache control"; + case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: + return "named maximum number of registers"; + case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS: + case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS: + return "raw access chain operands"; case SPV_OPERAND_TYPE_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: return "image"; @@ -360,6 +365,7 @@ bool spvOperandIsConcrete(spv_operand_type_t type) { case SPV_OPERAND_TYPE_HOST_ACCESS_QUALIFIER: case SPV_OPERAND_TYPE_LOAD_CACHE_CONTROL: case SPV_OPERAND_TYPE_STORE_CACHE_CONTROL: + case SPV_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS: return true; default: break; @@ -379,6 +385,7 @@ bool spvOperandIsConcreteMask(spv_operand_type_t type) { case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS: + case SPV_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS: return true; default: break; @@ -399,6 +406,7 @@ bool spvOperandIsOptional(spv_operand_type_t type) { case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: case SPV_OPERAND_TYPE_OPTIONAL_COOPERATIVE_MATRIX_OPERANDS: case SPV_OPERAND_TYPE_OPTIONAL_CIV: + case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS: return true; default: break; @@ -574,11 +582,13 @@ std::function spvOperandCanBeForwardDeclaredFunction( } std::function spvDbgInfoExtOperandCanBeForwardDeclaredFunction( - spv_ext_inst_type_t ext_type, uint32_t key) { + spv::Op opcode, 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 + // forward references except if used through OpExtInstWithForwardRefsKHR. if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) { - return [](unsigned) { return false; }; + return [opcode](unsigned) { + return opcode == spv::Op::OpExtInstWithForwardRefsKHR; + }; } // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward diff --git a/libs/bgfx/3rdparty/spirv-tools/source/operand.h b/libs/bgfx/3rdparty/spirv-tools/source/operand.h index a3010d9..3d42a05 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/operand.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/operand.h @@ -57,12 +57,6 @@ spv_result_t spvOperandTableValueLookup(spv_target_env, // Gets the name string of the non-variable operand type. const char* spvOperandTypeStr(spv_operand_type_t type); -// Returns true if the given type is concrete. -bool spvOperandIsConcrete(spv_operand_type_t type); - -// Returns true if the given type is concrete and also a mask. -bool spvOperandIsConcreteMask(spv_operand_type_t type); - // Returns true if an operand of the given type is optional. bool spvOperandIsOptional(spv_operand_type_t type); @@ -146,6 +140,6 @@ std::function spvOperandCanBeForwardDeclaredFunction( // of the operand can be forward declared. This function will // used in the SSA validation stage of the pipeline std::function spvDbgInfoExtOperandCanBeForwardDeclaredFunction( - spv_ext_inst_type_t ext_type, uint32_t key); + spv::Op opcode, spv_ext_inst_type_t ext_type, uint32_t key); #endif // SOURCE_OPERAND_H_ diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp index a487a45..6eebbb5 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/constants.cpp @@ -498,7 +498,7 @@ const Constant* ConstantManager::GetIntConst(uint64_t val, int32_t bitWidth, int32_t num_of_bit_to_ignore = 64 - bitWidth; val = static_cast(val << num_of_bit_to_ignore) >> num_of_bit_to_ignore; - } else { + } else if (bitWidth < 64) { // Clear the upper bit that are not used. uint64_t mask = ((1ull << bitWidth) - 1); val &= mask; @@ -511,7 +511,7 @@ const Constant* ConstantManager::GetIntConst(uint64_t val, int32_t bitWidth, // If the value is more than 32-bit, we need to split the operands into two // 32-bit integers. return GetConstant( - int_type, {static_cast(val >> 32), static_cast(val)}); + int_type, {static_cast(val), static_cast(val >> 32)}); } uint32_t ConstantManager::GetUIntConstId(uint32_t val) { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp index c82db41..d2da4d1 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/convert_to_sampled_image_pass.cpp @@ -329,12 +329,10 @@ bool ConvertToSampledImagePass::ConvertImageVariableToSampledImage( if (sampled_image_type == nullptr) return false; auto storage_class = GetStorageClass(*image_variable); if (storage_class == spv::StorageClass::Max) 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); + uint32_t type_id = context()->get_type_mgr()->FindPointerToType( + sampled_image_type_id, storage_class); MoveInstructionNextToType(image_variable, type_id); return true; } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp index 99711a1..e71032d 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/eliminate_dead_output_stores_pass.cpp @@ -92,16 +92,19 @@ void EliminateDeadOutputStoresPass::KillAllDeadStoresOfLocRef( }); // Compute offset and final type of reference. If no location found // or any stored locations are live, return without removing stores. - auto ptr_type = type_mgr->GetType(var->type_id())->AsPointer(); + + Instruction* ptr_type = get_def_use_mgr()->GetDef(var->type_id()); assert(ptr_type && "unexpected var type"); - auto var_type = ptr_type->pointee_type(); + const uint32_t kPointerTypePointeeIdx = 1; + uint32_t var_type_id = + ptr_type->GetSingleWordInOperand(kPointerTypePointeeIdx); uint32_t ref_loc = start_loc; - auto curr_type = var_type; if (ref->opcode() == spv::Op::OpAccessChain || ref->opcode() == spv::Op::OpInBoundsAccessChain) { - live_mgr->AnalyzeAccessChainLoc(ref, &curr_type, &ref_loc, &no_loc, - is_patch, /* input */ false); + var_type_id = live_mgr->AnalyzeAccessChainLoc( + ref, var_type_id, &ref_loc, &no_loc, is_patch, /* input */ false); } + const analysis::Type* curr_type = type_mgr->GetType(var_type_id); if (no_loc || AnyLocsAreLive(ref_loc, live_mgr->GetLocSize(curr_type))) return; // Kill all stores based on this reference diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp index 5c68e29..2497967 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/folding_rules.cpp @@ -1459,132 +1459,6 @@ FoldingRule FactorAddMuls() { }; } -// Replaces |inst| inplace with an FMA instruction |(x*y)+a|. -void ReplaceWithFma(Instruction* inst, uint32_t x, uint32_t y, uint32_t a) { - uint32_t ext = - inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); - - if (ext == 0) { - inst->context()->AddExtInstImport("GLSL.std.450"); - ext = inst->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); - assert(ext != 0 && - "Could not add the GLSL.std.450 extended instruction set"); - } - - std::vector operands; - operands.push_back({SPV_OPERAND_TYPE_ID, {ext}}); - operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {GLSLstd450Fma}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {x}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {a}}); - - inst->SetOpcode(spv::Op::OpExtInst); - inst->SetInOperands(std::move(operands)); -} - -// Folds a multiple and add into an Fma. -// -// Cases: -// (x * y) + a = Fma x y a -// a + (x * y) = Fma x y a -bool MergeMulAddArithmetic(IRContext* context, Instruction* inst, - const std::vector&) { - assert(inst->opcode() == spv::Op::OpFAdd); - - if (!inst->IsFloatingPointFoldingAllowed()) { - return false; - } - - analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - for (int i = 0; i < 2; i++) { - uint32_t op_id = inst->GetSingleWordInOperand(i); - Instruction* op_inst = def_use_mgr->GetDef(op_id); - - if (op_inst->opcode() != spv::Op::OpFMul) { - continue; - } - - if (!op_inst->IsFloatingPointFoldingAllowed()) { - continue; - } - - uint32_t x = op_inst->GetSingleWordInOperand(0); - uint32_t y = op_inst->GetSingleWordInOperand(1); - uint32_t a = inst->GetSingleWordInOperand((i + 1) % 2); - ReplaceWithFma(inst, x, y, a); - return true; - } - return false; -} - -// Replaces |sub| inplace with an FMA instruction |(x*y)+a| where |a| first gets -// negated if |negate_addition| is true, otherwise |x| gets negated. -void ReplaceWithFmaAndNegate(Instruction* sub, uint32_t x, uint32_t y, - uint32_t a, bool negate_addition) { - uint32_t ext = - sub->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); - - if (ext == 0) { - sub->context()->AddExtInstImport("GLSL.std.450"); - ext = sub->context()->get_feature_mgr()->GetExtInstImportId_GLSLstd450(); - assert(ext != 0 && - "Could not add the GLSL.std.450 extended instruction set"); - } - - InstructionBuilder ir_builder( - sub->context(), sub, - IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping); - - Instruction* neg = ir_builder.AddUnaryOp(sub->type_id(), spv::Op::OpFNegate, - negate_addition ? a : x); - uint32_t neg_op = neg->result_id(); // -a : -x - - std::vector operands; - operands.push_back({SPV_OPERAND_TYPE_ID, {ext}}); - operands.push_back({SPV_OPERAND_TYPE_LITERAL_INTEGER, {GLSLstd450Fma}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? x : neg_op}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {y}}); - operands.push_back({SPV_OPERAND_TYPE_ID, {negate_addition ? neg_op : a}}); - - sub->SetOpcode(spv::Op::OpExtInst); - sub->SetInOperands(std::move(operands)); -} - -// Folds a multiply and subtract into an Fma and negation. -// -// Cases: -// (x * y) - a = Fma x y -a -// a - (x * y) = Fma -x y a -bool MergeMulSubArithmetic(IRContext* context, Instruction* sub, - const std::vector&) { - assert(sub->opcode() == spv::Op::OpFSub); - - if (!sub->IsFloatingPointFoldingAllowed()) { - return false; - } - - analysis::DefUseManager* def_use_mgr = context->get_def_use_mgr(); - for (int i = 0; i < 2; i++) { - uint32_t op_id = sub->GetSingleWordInOperand(i); - Instruction* mul = def_use_mgr->GetDef(op_id); - - if (mul->opcode() != spv::Op::OpFMul) { - continue; - } - - if (!mul->IsFloatingPointFoldingAllowed()) { - continue; - } - - uint32_t x = mul->GetSingleWordInOperand(0); - uint32_t y = mul->GetSingleWordInOperand(1); - uint32_t a = sub->GetSingleWordInOperand((i + 1) % 2); - ReplaceWithFmaAndNegate(sub, x, y, a, i == 0); - return true; - } - return false; -} - FoldingRule IntMultipleBy1() { return [](IRContext*, Instruction* inst, const std::vector& constants) { @@ -1733,27 +1607,26 @@ bool CompositeConstructFeedingExtract( } // Walks the indexes chain from |start| to |end| of an OpCompositeInsert or -// OpCompositeExtract instruction, and returns the type of the final element -// being accessed. -const analysis::Type* GetElementType(uint32_t type_id, - Instruction::iterator start, - Instruction::iterator end, - const analysis::TypeManager* type_mgr) { - const analysis::Type* type = type_mgr->GetType(type_id); +// OpCompositeExtract instruction, and returns the type id of the final element +// being accessed. Returns 0 if a valid type could not be found. +uint32_t GetElementType(uint32_t type_id, Instruction::iterator start, + Instruction::iterator end, + const analysis::DefUseManager* def_use_manager) { for (auto index : make_range(std::move(start), std::move(end))) { + const Instruction* type_inst = def_use_manager->GetDef(type_id); assert(index.type == SPV_OPERAND_TYPE_LITERAL_INTEGER && index.words.size() == 1); - if (auto* array_type = type->AsArray()) { - type = array_type->element_type(); - } else if (auto* matrix_type = type->AsMatrix()) { - type = matrix_type->element_type(); - } else if (auto* struct_type = type->AsStruct()) { - type = struct_type->element_types()[index.words[0]]; + if (type_inst->opcode() == spv::Op::OpTypeArray) { + type_id = type_inst->GetSingleWordInOperand(0); + } else if (type_inst->opcode() == spv::Op::OpTypeMatrix) { + type_id = type_inst->GetSingleWordInOperand(0); + } else if (type_inst->opcode() == spv::Op::OpTypeStruct) { + type_id = type_inst->GetSingleWordInOperand(index.words[0]); } else { - type = nullptr; + return 0; } } - return type; + return type_id; } // Returns true of |inst_1| and |inst_2| have the same indexes that will be used @@ -1838,16 +1711,11 @@ bool CompositeExtractFeedingConstruct( // The last check it to see that the object being extracted from is the // correct type. Instruction* original_inst = def_use_mgr->GetDef(original_id); - analysis::TypeManager* type_mgr = context->get_type_mgr(); - const analysis::Type* original_type = + uint32_t original_type_id = GetElementType(original_inst->type_id(), first_element_inst->begin() + 3, - first_element_inst->end() - 1, type_mgr); - - if (original_type == nullptr) { - return false; - } + first_element_inst->end() - 1, def_use_mgr); - if (inst->type_id() != type_mgr->GetId(original_type)) { + if (inst->type_id() != original_type_id) { return false; } @@ -2137,13 +2005,15 @@ bool DoInsertedValuesCoverEntireObject( return true; } -// Returns the type of the element that immediately contains the element being -// inserted by the OpCompositeInsert instruction |inst|. -const analysis::Type* GetContainerType(Instruction* inst) { +// Returns id of the type of the element that immediately contains the element +// being inserted by the OpCompositeInsert instruction |inst|. Returns 0 if it +// could not be found. +uint32_t GetContainerTypeId(Instruction* inst) { assert(inst->opcode() == spv::Op::OpCompositeInsert); - analysis::TypeManager* type_mgr = inst->context()->get_type_mgr(); - return GetElementType(inst->type_id(), inst->begin() + 4, inst->end() - 1, - type_mgr); + analysis::DefUseManager* def_use_manager = inst->context()->get_def_use_mgr(); + uint32_t container_type_id = GetElementType( + inst->type_id(), inst->begin() + 4, inst->end() - 1, def_use_manager); + return container_type_id; } // Returns an OpCompositeConstruct instruction that build an object with @@ -2190,18 +2060,20 @@ bool CompositeInsertToCompositeConstruct( if (inst->NumInOperands() < 3) return false; std::map values_inserted = GetInsertedValues(inst); - const analysis::Type* container_type = GetContainerType(inst); - if (container_type == nullptr) { + uint32_t container_type_id = GetContainerTypeId(inst); + if (container_type_id == 0) { return false; } + analysis::TypeManager* type_mgr = context->get_type_mgr(); + const analysis::Type* container_type = type_mgr->GetType(container_type_id); + assert(container_type && "GetContainerTypeId returned a bad id."); if (!DoInsertedValuesCoverEntireObject(container_type, values_inserted)) { return false; } - analysis::TypeManager* type_mgr = context->get_type_mgr(); - Instruction* construct = BuildCompositeConstruct( - type_mgr->GetId(container_type), values_inserted, inst); + Instruction* construct = + BuildCompositeConstruct(container_type_id, values_inserted, inst); InsertConstructedObject(inst, construct); return true; } @@ -2941,7 +2813,6 @@ void FoldingRules::AddFoldingRules() { rules_[spv::Op::OpFAdd].push_back(MergeAddSubArithmetic()); rules_[spv::Op::OpFAdd].push_back(MergeGenericAddSubArithmetic()); rules_[spv::Op::OpFAdd].push_back(FactorAddMuls()); - rules_[spv::Op::OpFAdd].push_back(MergeMulAddArithmetic); rules_[spv::Op::OpFDiv].push_back(RedundantFDiv()); rules_[spv::Op::OpFDiv].push_back(ReciprocalFDiv()); @@ -2962,7 +2833,6 @@ void FoldingRules::AddFoldingRules() { rules_[spv::Op::OpFSub].push_back(MergeSubNegateArithmetic()); rules_[spv::Op::OpFSub].push_back(MergeSubAddArithmetic()); rules_[spv::Op::OpFSub].push_back(MergeSubSubArithmetic()); - rules_[spv::Op::OpFSub].push_back(MergeMulSubArithmetic); rules_[spv::Op::OpIAdd].push_back(RedundantIAdd()); rules_[spv::Op::OpIAdd].push_back(MergeAddNegateArithmetic()); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp index 3f160b2..3186433 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/inline_pass.cpp @@ -213,6 +213,19 @@ uint32_t InlinePass::CreateReturnVar( {(uint32_t)spv::StorageClass::Function}}})); new_vars->push_back(std::move(var_inst)); get_decoration_mgr()->CloneDecorations(calleeFn->result_id(), returnVarId); + + // Decorate the return var with AliasedPointer if the storage class of the + // pointee type is PhysicalStorageBuffer. + auto const pointee_type = + type_mgr->GetType(returnVarTypeId)->AsPointer()->pointee_type(); + if (pointee_type->AsPointer() != nullptr) { + if (pointee_type->AsPointer()->storage_class() == + spv::StorageClass::PhysicalStorageBuffer) { + get_decoration_mgr()->AddDecoration( + returnVarId, uint32_t(spv::Decoration::AliasedPointer)); + } + } + return returnVarId; } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp index 239d316..d864b7c 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.cpp @@ -88,6 +88,9 @@ void IRContext::BuildInvalidAnalyses(IRContext::Analysis set) { if (set & kAnalysisDebugInfo) { BuildDebugInfoManager(); } + if (set & kAnalysisLiveness) { + BuildLivenessManager(); + } } void IRContext::InvalidateAnalysesExceptFor( diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h index 5685db8..3857696 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_context.h @@ -84,7 +84,7 @@ class IRContext { kAnalysisTypes = 1 << 15, kAnalysisDebugInfo = 1 << 16, kAnalysisLiveness = 1 << 17, - kAnalysisEnd = 1 << 17 + kAnalysisEnd = 1 << 18 }; using ProcessFunction = std::function; @@ -202,8 +202,9 @@ class IRContext { inline IteratorRange debugs3() const; // Iterators for debug info instructions (excluding OpLine & OpNoLine) - // contained in this module. These are OpExtInst for DebugInfo extension - // placed between section 9 and 10. + // contained in this module. These are OpExtInst & + // OpExtInstWithForwardRefsKHR for DebugInfo extension placed between section + // 9 and 10. inline Module::inst_iterator ext_inst_debuginfo_begin(); inline Module::inst_iterator ext_inst_debuginfo_end(); inline IteratorRange ext_inst_debuginfo(); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp index e9b7bbf..a785048 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/ir_loader.cpp @@ -42,7 +42,7 @@ IrLoader::IrLoader(const MessageConsumer& consumer, Module* m) bool IsLineInst(const spv_parsed_instruction_t* inst) { const auto opcode = static_cast(inst->opcode); if (IsOpLineInst(opcode)) return true; - if (opcode != spv::Op::OpExtInst) return false; + if (!spvIsExtendedInstruction(opcode)) 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]; @@ -65,7 +65,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { // create a new instruction, but simply keep the information in // struct DebugScope. const auto opcode = static_cast(inst->opcode); - if (opcode == spv::Op::OpExtInst && + if (spvIsExtendedInstruction(opcode) && 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 || @@ -209,10 +209,10 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { } else if (IsConstantInst(opcode) || opcode == spv::Op::OpVariable || opcode == spv::Op::OpUndef) { module_->AddGlobalValue(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtInst && + } else if (spvIsExtendedInstruction(opcode) && spvExtInstIsDebugInfo(inst->ext_inst_type)) { module_->AddExtInstDebugInfo(std::move(spv_inst)); - } else if (opcode == spv::Op::OpExtInst && + } else if (spvIsExtendedInstruction(opcode) && spvExtInstIsNonSemantic(inst->ext_inst_type)) { // If there are no functions, add the non-semantic instructions to the // global values. Otherwise append it to the list of the last function. @@ -235,7 +235,7 @@ bool IrLoader::AddInstruction(const spv_parsed_instruction_t* inst) { last_dbg_scope_ = DebugScope(kNoDebugScope, kNoInlinedAt); if (last_dbg_scope_.GetLexicalScope() != kNoDebugScope) spv_inst->SetDebugScope(last_dbg_scope_); - if (opcode == spv::Op::OpExtInst && + if (spvIsExtendedInstruction(opcode) && 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) { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.cpp index 336f3ae..dae705d 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.cpp @@ -123,21 +123,29 @@ uint32_t LivenessManager::GetLocSize(const analysis::Type* type) const { return 1; } -const analysis::Type* LivenessManager::GetComponentType( - uint32_t index, const analysis::Type* agg_type) const { - auto arr_type = agg_type->AsArray(); - if (arr_type) return arr_type->element_type(); - auto struct_type = agg_type->AsStruct(); - if (struct_type) return struct_type->element_types()[index]; - auto mat_type = agg_type->AsMatrix(); - if (mat_type) return mat_type->element_type(); - auto vec_type = agg_type->AsVector(); - assert(vec_type && "unexpected non-aggregate type"); - return vec_type->element_type(); +uint32_t LivenessManager::GetComponentType(uint32_t index, + uint32_t agg_type_id) const { + analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); + Instruction* agg_type_inst = def_use_mgr->GetDef(agg_type_id); + + const uint32_t kArrayElementInIdx = 0; + switch (agg_type_inst->opcode()) { + case spv::Op::OpTypeArray: + case spv::Op::OpTypeMatrix: + case spv::Op::OpTypeVector: + return agg_type_inst->GetSingleWordInOperand(kArrayElementInIdx); + case spv::Op::OpTypeStruct: + return agg_type_inst->GetSingleWordInOperand(index); + default: + assert(false && "unexpected aggregate type"); + return 0; + } } uint32_t LivenessManager::GetLocOffset(uint32_t index, - const analysis::Type* agg_type) const { + uint32_t agg_type_id) const { + analysis::TypeManager* type_mgr = context()->get_type_mgr(); + const analysis::Type* agg_type = type_mgr->GetType(agg_type_id); auto arr_type = agg_type->AsArray(); if (arr_type) return index * GetLocSize(arr_type->element_type()); auto struct_type = agg_type->AsStruct(); @@ -161,12 +169,11 @@ uint32_t LivenessManager::GetLocOffset(uint32_t index, return 0; } -void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, - const analysis::Type** curr_type, - uint32_t* offset, bool* no_loc, - bool is_patch, bool input) { +uint32_t LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, + uint32_t curr_type_id, + uint32_t* offset, bool* no_loc, + bool is_patch, bool input) { analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); analysis::DecorationManager* deco_mgr = context()->get_decoration_mgr(); // For tesc, tese and geom input variables, and tesc output variables, // first array index does not contribute to offset. @@ -178,15 +185,18 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, (!input && stage == spv::ExecutionModel::TessellationControl)) skip_first_index = !is_patch; uint32_t ocnt = 0; - ac->WhileEachInOperand([this, &ocnt, def_use_mgr, type_mgr, deco_mgr, - curr_type, offset, no_loc, + ac->WhileEachInOperand([this, &ocnt, def_use_mgr, deco_mgr, &curr_type_id, + offset, no_loc, skip_first_index](const uint32_t* opnd) { if (ocnt >= 1) { // Skip first index's contribution to offset if indicated + Instruction* curr_type_inst = def_use_mgr->GetDef(curr_type_id); if (ocnt == 1 && skip_first_index) { - auto arr_type = (*curr_type)->AsArray(); - assert(arr_type && "unexpected wrapper type"); - *curr_type = arr_type->element_type(); + assert(curr_type_inst->opcode() == spv::Op::OpTypeArray && + "unexpected wrapper type"); + const uint32_t kArrayElementTypeInIdx = 0; + curr_type_id = + curr_type_inst->GetSingleWordInOperand(kArrayElementTypeInIdx); ocnt++; return true; } @@ -196,12 +206,10 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, // If current type is struct, look for location decoration on member and // reset offset if found. auto index = idx_inst->GetSingleWordInOperand(0); - auto str_type = (*curr_type)->AsStruct(); - if (str_type) { + if (curr_type_inst->opcode() == spv::Op::OpTypeStruct) { uint32_t loc = 0; - auto str_type_id = type_mgr->GetId(str_type); bool no_mem_loc = deco_mgr->WhileEachDecoration( - str_type_id, uint32_t(spv::Decoration::Location), + curr_type_id, uint32_t(spv::Decoration::Location), [&loc, index, no_loc](const Instruction& deco) { assert(deco.opcode() == spv::Op::OpMemberDecorate && "unexpected decoration"); @@ -216,19 +224,20 @@ void LivenessManager::AnalyzeAccessChainLoc(const Instruction* ac, }); if (!no_mem_loc) { *offset = loc; - *curr_type = GetComponentType(index, *curr_type); + curr_type_id = curr_type_inst->GetSingleWordInOperand(index); ocnt++; return true; } } // Update offset and current type based on constant index. - *offset += GetLocOffset(index, *curr_type); - *curr_type = GetComponentType(index, *curr_type); + *offset += GetLocOffset(index, curr_type_id); + curr_type_id = GetComponentType(index, curr_type_id); } ocnt++; return true; }); + return curr_type_id; } void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { @@ -268,8 +277,15 @@ void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { // through constant indices and mark those locs live. Assert if no location // found. uint32_t offset = loc; - auto curr_type = var_type; - AnalyzeAccessChainLoc(ref, &curr_type, &offset, &no_loc, is_patch); + Instruction* ptr_type_inst = + context()->get_def_use_mgr()->GetDef(var->type_id()); + assert(ptr_type && "unexpected var type"); + const uint32_t kPointerTypePointeeIdx = 1; + uint32_t var_type_id = + ptr_type_inst->GetSingleWordInOperand(kPointerTypePointeeIdx); + uint32_t curr_type_id = + AnalyzeAccessChainLoc(ref, var_type_id, &offset, &no_loc, is_patch); + auto curr_type = type_mgr->GetType(curr_type_id); assert(!no_loc && "missing input variable location"); MarkLocsLive(offset, GetLocSize(curr_type)); } @@ -277,15 +293,18 @@ void LivenessManager::MarkRefLive(const Instruction* ref, Instruction* var) { void LivenessManager::ComputeLiveness() { InitializeAnalysis(); analysis::DefUseManager* def_use_mgr = context()->get_def_use_mgr(); - analysis::TypeManager* type_mgr = context()->get_type_mgr(); // Process all input variables for (auto& var : context()->types_values()) { if (var.opcode() != spv::Op::OpVariable) { continue; } - analysis::Type* var_type = type_mgr->GetType(var.type_id()); - analysis::Pointer* ptr_type = var_type->AsPointer(); - if (ptr_type->storage_class() != spv::StorageClass::Input) { + Instruction* var_type_inst = def_use_mgr->GetDef(var.type_id()); + assert(var_type_inst->opcode() == spv::Op::OpTypePointer && + "Expected a pointer type"); + const uint32_t kPointerTypeStorageClassInIdx = 0; + spv::StorageClass sc = static_cast( + var_type_inst->GetSingleWordInOperand(kPointerTypeStorageClassInIdx)); + if (sc != spv::StorageClass::Input) { continue; } // If var is builtin, mark live if analyzed and continue to next variable @@ -295,14 +314,15 @@ void LivenessManager::ComputeLiveness() { // continue to next variable. Input interface blocks will only appear // in tesc, tese and geom shaders. Will need to strip off one level of // arrayness to get to block type. - auto pte_type = ptr_type->pointee_type(); - auto arr_type = pte_type->AsArray(); - if (arr_type) { - auto elt_type = arr_type->element_type(); - auto str_type = elt_type->AsStruct(); - if (str_type) { - auto str_type_id = type_mgr->GetId(str_type); - if (AnalyzeBuiltIn(str_type_id)) continue; + const uint32_t kPointerTypePointeeTypeInIdx = 1; + uint32_t pte_type_id = + var_type_inst->GetSingleWordInOperand(kPointerTypePointeeTypeInIdx); + Instruction* pte_type_inst = def_use_mgr->GetDef(pte_type_id); + if (pte_type_inst->opcode() == spv::Op::OpTypeArray) { + uint32_t array_elt_type_id = pte_type_inst->GetSingleWordInOperand(0); + Instruction* arr_elt_type = def_use_mgr->GetDef(array_elt_type_id); + if (arr_elt_type->opcode() == spv::Op::OpTypeStruct) { + if (AnalyzeBuiltIn(array_elt_type_id)) continue; } } // Mark all used locations of var live diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.h index 7d8a9fb..7050005 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/liveness.h @@ -41,13 +41,13 @@ class LivenessManager { // Return true if builtin |bi| is being analyzed. bool IsAnalyzedBuiltin(uint32_t bi); - // Determine starting loc |offset| and the type |cur_type| of - // access chain |ac|. Set |no_loc| to true if no loc found. - // |is_patch| indicates if patch variable. |input| is true - // if input variable, otherwise output variable. - void AnalyzeAccessChainLoc(const Instruction* ac, - const analysis::Type** curr_type, uint32_t* offset, - bool* no_loc, bool is_patch, bool input = true); + // Return the result type of |ac| when applied to |cur_type_id|. Set + // |no_loc| to true if no loc found. Set |is_patch| indicates if the variable + // is a patch variable. Set |input| if the variable is an input variable. + // Otherwise it is assumed that the variable is an output variable. + uint32_t AnalyzeAccessChainLoc(const Instruction* ac, uint32_t curr_type_id, + uint32_t* offset, bool* no_loc, bool is_patch, + bool input = true); // Return size of |type_id| in units of locations uint32_t GetLocSize(const analysis::Type* type) const; @@ -68,13 +68,12 @@ class LivenessManager { // Mark |count| locations starting at location |start|. void MarkLocsLive(uint32_t start, uint32_t count); - // Return type of component of aggregate type |agg_type| at |index| - const analysis::Type* GetComponentType(uint32_t index, - const analysis::Type* agg_type) const; + // Return type of the member |index| in the aggregate type |agg_type_id|. + uint32_t GetComponentType(uint32_t index, uint32_t agg_type_id) const; - // Return offset of |index| into aggregate type |agg_type| in units of - // input locations - uint32_t GetLocOffset(uint32_t index, const analysis::Type* agg_type) const; + // Return offset of member |index| in the aggregate type |agg_type_id| in + // units of input locations. + uint32_t GetLocOffset(uint32_t index, uint32_t agg_type_id) const; // Populate live_locs_ and live_builtins_ void ComputeLiveness(); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.cpp new file mode 100644 index 0000000..8684feb --- /dev/null +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.cpp @@ -0,0 +1,112 @@ +// Copyright (c) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/opt/opextinst_forward_ref_fixup_pass.h" + +#include +#include + +#include "source/extensions.h" +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "type_manager.h" + +namespace spvtools { +namespace opt { +namespace { + +// Returns true if the instruction |inst| has a forward reference to another +// debug instruction. +// |debug_ids| contains the list of IDs belonging to debug instructions. +// |seen_ids| contains the list of IDs already seen. +bool HasForwardReference(const Instruction& inst, + const std::unordered_set& debug_ids, + const std::unordered_set& seen_ids) { + const uint32_t num_in_operands = inst.NumInOperands(); + for (uint32_t i = 0; i < num_in_operands; ++i) { + const Operand& op = inst.GetInOperand(i); + if (!spvIsIdType(op.type)) continue; + + if (debug_ids.count(op.AsId()) == 0) continue; + + if (seen_ids.count(op.AsId()) == 0) return true; + } + + return false; +} + +// Replace |inst| opcode with OpExtInstWithForwardRefsKHR or OpExtInst +// if required to comply with forward references. +bool ReplaceOpcodeIfRequired(Instruction& inst, bool hasForwardReferences) { + if (hasForwardReferences && + inst.opcode() != spv::Op::OpExtInstWithForwardRefsKHR) + inst.SetOpcode(spv::Op::OpExtInstWithForwardRefsKHR); + else if (!hasForwardReferences && inst.opcode() != spv::Op::OpExtInst) + inst.SetOpcode(spv::Op::OpExtInst); + else + return false; + return true; +} + +// Returns all the result IDs of the instructions in |range|. +std::unordered_set gatherResultIds( + const IteratorRange& range) { + std::unordered_set output; + for (const auto& it : range) output.insert(it.result_id()); + return output; +} + +} // namespace + +Pass::Status OpExtInstWithForwardReferenceFixupPass::Process() { + std::unordered_set seen_ids = + gatherResultIds(get_module()->ext_inst_imports()); + std::unordered_set debug_ids = + gatherResultIds(get_module()->ext_inst_debuginfo()); + for (uint32_t id : seen_ids) debug_ids.insert(id); + + bool moduleChanged = false; + bool hasAtLeastOneForwardReference = false; + IRContext* ctx = context(); + for (Instruction& inst : get_module()->ext_inst_debuginfo()) { + if (inst.opcode() != spv::Op::OpExtInst && + inst.opcode() != spv::Op::OpExtInstWithForwardRefsKHR) + continue; + + seen_ids.insert(inst.result_id()); + bool hasForwardReferences = HasForwardReference(inst, debug_ids, seen_ids); + hasAtLeastOneForwardReference |= hasForwardReferences; + + if (ReplaceOpcodeIfRequired(inst, hasForwardReferences)) { + moduleChanged = true; + ctx->AnalyzeUses(&inst); + } + } + + if (hasAtLeastOneForwardReference != + ctx->get_feature_mgr()->HasExtension( + kSPV_KHR_relaxed_extended_instruction)) { + if (hasAtLeastOneForwardReference) + ctx->AddExtension("SPV_KHR_relaxed_extended_instruction"); + else + ctx->RemoveExtension(Extension::kSPV_KHR_relaxed_extended_instruction); + moduleChanged = true; + } + + return moduleChanged ? Status::SuccessWithChange + : Status::SuccessWithoutChange; +} + +} // namespace opt +} // namespace spvtools diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.h new file mode 100644 index 0000000..26e5b81 --- /dev/null +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/opextinst_forward_ref_fixup_pass.h @@ -0,0 +1,48 @@ +// Copyright (c) 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H +#define SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H + +#include "source/opt/ir_context.h" +#include "source/opt/module.h" +#include "source/opt/pass.h" + +namespace spvtools { +namespace opt { + +class OpExtInstWithForwardReferenceFixupPass : public Pass { + public: + const char* name() const override { return "fix-opextinst-opcodes"; } + Status Process() override; + + IRContext::Analysis GetPreservedAnalyses() override { + return IRContext::kAnalysisInstrToBlockMapping | + IRContext::kAnalysisDecorations | IRContext::kAnalysisCombinators | + IRContext::kAnalysisCFG | IRContext::kAnalysisDominatorAnalysis | + IRContext::kAnalysisLoopAnalysis | IRContext::kAnalysisNameMap | + IRContext::kAnalysisScalarEvolution | + IRContext::kAnalysisRegisterPressure | + IRContext::kAnalysisValueNumberTable | + IRContext::kAnalysisStructuredCFG | + IRContext::kAnalysisBuiltinVarId | + IRContext::kAnalysisIdToFuncMapping | IRContext::kAnalysisTypes | + IRContext::kAnalysisDefUse | IRContext::kAnalysisConstants; + } +}; + +} // namespace opt +} // namespace spvtools + +#endif // SOURCE_OPT_OPEXTINST_FORWARD_REF_FIXUP_H diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp index c4c2b0f..4add68a 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/optimizer.cpp @@ -169,7 +169,8 @@ Optimizer& Optimizer::RegisterLegalizationPasses(bool preserve_interface) { .RegisterPass(CreateAggressiveDCEPass(preserve_interface)) .RegisterPass(CreateRemoveUnusedInterfaceVariablesPass()) .RegisterPass(CreateInterpolateFixupPass()) - .RegisterPass(CreateInvocationInterlockPlacementPass()); + .RegisterPass(CreateInvocationInterlockPlacementPass()) + .RegisterPass(CreateOpExtInstWithForwardReferenceFixupPass()); } Optimizer& Optimizer::RegisterLegalizationPasses() { @@ -323,6 +324,8 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag, RegisterPass(CreateStripReflectInfoPass()); } else if (pass_name == "strip-nonsemantic") { RegisterPass(CreateStripNonSemanticInfoPass()); + } else if (pass_name == "fix-opextinst-opcodes") { + RegisterPass(CreateOpExtInstWithForwardReferenceFixupPass()); } else if (pass_name == "set-spec-const-default-value") { if (pass_args.size() > 0) { auto spec_ids_vals = @@ -451,16 +454,6 @@ bool Optimizer::RegisterPassFromFlag(const std::string& flag, RegisterPass(CreateWorkaround1209Pass()); } else if (pass_name == "replace-invalid-opcode") { RegisterPass(CreateReplaceInvalidOpcodePass()); - } else if (pass_name == "inst-bindless-check" || - pass_name == "inst-desc-idx-check" || - pass_name == "inst-buff-oob-check") { - // preserve legacy names - RegisterPass(CreateInstBindlessCheckPass(23)); - RegisterPass(CreateSimplificationPass()); - RegisterPass(CreateDeadBranchElimPass()); - RegisterPass(CreateBlockMergePass()); - } else if (pass_name == "inst-buff-addr-check") { - RegisterPass(CreateInstBuffAddrCheckPass(23)); } else if (pass_name == "convert-relaxed-to-half") { RegisterPass(CreateConvertRelaxedToHalfPass()); } else if (pass_name == "relax-float-ops") { @@ -1023,22 +1016,12 @@ Optimizer::PassToken CreateUpgradeMemoryModelPass() { MakeUnique()); } -Optimizer::PassToken CreateInstBindlessCheckPass(uint32_t shader_id) { - return MakeUnique( - MakeUnique(shader_id)); -} - Optimizer::PassToken CreateInstDebugPrintfPass(uint32_t desc_set, uint32_t shader_id) { return MakeUnique( MakeUnique(desc_set, shader_id)); } -Optimizer::PassToken CreateInstBuffAddrCheckPass(uint32_t shader_id) { - return MakeUnique( - MakeUnique(shader_id)); -} - Optimizer::PassToken CreateConvertRelaxedToHalfPass() { return MakeUnique( MakeUnique()); @@ -1166,6 +1149,12 @@ Optimizer::PassToken CreateModifyMaximalReconvergencePass(bool add) { return MakeUnique( MakeUnique(add)); } + +Optimizer::PassToken CreateOpExtInstWithForwardReferenceFixupPass() { + return MakeUnique( + MakeUnique()); +} + } // namespace spvtools extern "C" { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/passes.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/passes.h index 9d027fb..ac68ccd 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/passes.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/passes.h @@ -48,8 +48,6 @@ #include "source/opt/if_conversion.h" #include "source/opt/inline_exhaustive_pass.h" #include "source/opt/inline_opaque_pass.h" -#include "source/opt/inst_bindless_check_pass.h" -#include "source/opt/inst_buff_addr_check_pass.h" #include "source/opt/inst_debug_printf_pass.h" #include "source/opt/interface_var_sroa.h" #include "source/opt/interp_fixup_pass.h" @@ -67,6 +65,7 @@ #include "source/opt/merge_return_pass.h" #include "source/opt/modify_maximal_reconvergence.h" #include "source/opt/null_pass.h" +#include "source/opt/opextinst_forward_ref_fixup_pass.h" #include "source/opt/private_to_local_pass.h" #include "source/opt/reduce_load_size.h" #include "source/opt/redundancy_elimination.h" diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp index f81bced..118d846 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_debug_info_pass.cpp @@ -43,7 +43,7 @@ Pass::Status StripDebugInfoPass::Process() { // see if this string is used anywhere by a non-semantic instruction bool no_nonsemantic_use = def_use->WhileEachUser(&inst, [def_use](Instruction* use) { - if (use->opcode() == spv::Op::OpExtInst) { + if (spvIsExtendedInstruction(use->opcode())) { auto ext_inst_set = def_use->GetDef(use->GetSingleWordInOperand(0u)); const std::string extension_name = diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp index 3886835..659849e 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/strip_nonsemantic_info_pass.cpp @@ -96,7 +96,7 @@ Pass::Status StripNonSemanticInfoPass::Process() { if (!non_semantic_sets.empty()) { context()->module()->ForEachInst( [&non_semantic_sets, &to_remove](Instruction* inst) { - if (inst->opcode() == spv::Op::OpExtInst) { + if (spvIsExtendedInstruction(inst->opcode())) { if (non_semantic_sets.find(inst->GetSingleWordInOperand(0)) != non_semantic_sets.end()) { to_remove.push_back(inst); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp index 24f9e46..aaf4d32 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.cpp @@ -399,6 +399,33 @@ ExtensionSet getExtensionsRelatedTo(const CapabilitySet& capabilities, return output; } + +bool hasOpcodeConflictingCapabilities(spv::Op opcode) { + switch (opcode) { + case spv::Op::OpBeginInvocationInterlockEXT: + case spv::Op::OpEndInvocationInterlockEXT: + case spv::Op::OpGroupNonUniformIAdd: + case spv::Op::OpGroupNonUniformFAdd: + case spv::Op::OpGroupNonUniformIMul: + case spv::Op::OpGroupNonUniformFMul: + case spv::Op::OpGroupNonUniformSMin: + case spv::Op::OpGroupNonUniformUMin: + case spv::Op::OpGroupNonUniformFMin: + case spv::Op::OpGroupNonUniformSMax: + case spv::Op::OpGroupNonUniformUMax: + case spv::Op::OpGroupNonUniformFMax: + case spv::Op::OpGroupNonUniformBitwiseAnd: + case spv::Op::OpGroupNonUniformBitwiseOr: + case spv::Op::OpGroupNonUniformBitwiseXor: + case spv::Op::OpGroupNonUniformLogicalAnd: + case spv::Op::OpGroupNonUniformLogicalOr: + case spv::Op::OpGroupNonUniformLogicalXor: + return true; + default: + return false; + } +} + } // namespace TrimCapabilitiesPass::TrimCapabilitiesPass() @@ -416,10 +443,7 @@ TrimCapabilitiesPass::TrimCapabilitiesPass() void TrimCapabilitiesPass::addInstructionRequirementsForOpcode( spv::Op opcode, CapabilitySet* capabilities, ExtensionSet* extensions) const { - // Ignoring OpBeginInvocationInterlockEXT and OpEndInvocationInterlockEXT - // because they have three possible capabilities, only one of which is needed - if (opcode == spv::Op::OpBeginInvocationInterlockEXT || - opcode == spv::Op::OpEndInvocationInterlockEXT) { + if (hasOpcodeConflictingCapabilities(opcode)) { return; } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h index 3a8460f..3ff6dba 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/trim_capabilities_pass.h @@ -81,6 +81,11 @@ class TrimCapabilitiesPass : public Pass { spv::Capability::FragmentShaderPixelInterlockEXT, spv::Capability::FragmentShaderSampleInterlockEXT, spv::Capability::FragmentShaderShadingRateInterlockEXT, + spv::Capability::GroupNonUniform, + spv::Capability::GroupNonUniformArithmetic, + spv::Capability::GroupNonUniformClustered, + spv::Capability::GroupNonUniformPartitionedNV, + spv::Capability::GroupNonUniformVote, spv::Capability::Groups, spv::Capability::ImageMSArray, spv::Capability::Int16, @@ -98,7 +103,7 @@ class TrimCapabilitiesPass : public Pass { spv::Capability::StoragePushConstant16, spv::Capability::StorageUniform16, spv::Capability::StorageUniformBufferBlock16, - spv::Capability::VulkanMemoryModelDeviceScope + spv::Capability::VulkanMemoryModelDeviceScope, // clang-format on }; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.cpp b/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.cpp index ae32077..62f9369 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.cpp @@ -454,12 +454,7 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, spv::StorageClass storage_class) { Type* pointeeTy = GetType(type_id); Pointer pointerTy(pointeeTy, storage_class); - if (pointeeTy->IsUniqueType()) { - // Non-ambiguous type. Get the pointer type through the type manager. - return GetTypeInstruction(&pointerTy); - } - // Ambiguous type, do a linear search. Module::inst_iterator type_itr = context()->module()->types_values_begin(); for (; type_itr != context()->module()->types_values_end(); ++type_itr) { const Instruction* type_inst = &*type_itr; @@ -472,8 +467,10 @@ uint32_t TypeManager::FindPointerToType(uint32_t type_id, } // Must create the pointer type. - // TODO(1841): Handle id overflow. uint32_t resultId = context()->TakeNextId(); + if (resultId == 0) { + return 0; + } std::unique_ptr type_inst( new Instruction(context(), spv::Op::OpTypePointer, 0, resultId, {{spv_operand_type_t::SPV_OPERAND_TYPE_STORAGE_CLASS, @@ -517,13 +514,24 @@ void TypeManager::CreateDecoration(uint32_t target, context()->get_def_use_mgr()->AnalyzeInstUse(inst); } -Type* TypeManager::RebuildType(const Type& type) { +Type* TypeManager::RebuildType(uint32_t type_id, const Type& type) { + assert(type_id != 0); + // The comparison and hash on the type pool will avoid inserting the rebuilt // type if an equivalent type already exists. The rebuilt type will be deleted // when it goes out of scope at the end of the function in that case. Repeated // insertions of the same Type will, at most, keep one corresponding object in // the type pool. std::unique_ptr rebuilt_ty; + + // If |type_id| is already present in the type pool, return the existing type. + // This saves extra work in the type builder and prevents running into + // circular issues (https://github.com/KhronosGroup/SPIRV-Tools/issues/5623). + Type* pool_ty = GetType(type_id); + if (pool_ty != nullptr) { + return pool_ty; + } + switch (type.kind()) { #define DefineNoSubtypeCase(kind) \ case Type::k##kind: \ @@ -550,43 +558,46 @@ Type* TypeManager::RebuildType(const Type& type) { case Type::kVector: { const Vector* vec_ty = type.AsVector(); const Type* ele_ty = vec_ty->element_type(); - rebuilt_ty = - MakeUnique(RebuildType(*ele_ty), vec_ty->element_count()); + rebuilt_ty = MakeUnique(RebuildType(GetId(ele_ty), *ele_ty), + vec_ty->element_count()); break; } case Type::kMatrix: { const Matrix* mat_ty = type.AsMatrix(); const Type* ele_ty = mat_ty->element_type(); - rebuilt_ty = - MakeUnique(RebuildType(*ele_ty), mat_ty->element_count()); + rebuilt_ty = MakeUnique(RebuildType(GetId(ele_ty), *ele_ty), + mat_ty->element_count()); break; } case Type::kImage: { const Image* image_ty = type.AsImage(); const Type* ele_ty = image_ty->sampled_type(); - rebuilt_ty = - MakeUnique(RebuildType(*ele_ty), image_ty->dim(), - image_ty->depth(), image_ty->is_arrayed(), - image_ty->is_multisampled(), image_ty->sampled(), - image_ty->format(), image_ty->access_qualifier()); + rebuilt_ty = MakeUnique( + RebuildType(GetId(ele_ty), *ele_ty), image_ty->dim(), + image_ty->depth(), image_ty->is_arrayed(), + image_ty->is_multisampled(), image_ty->sampled(), image_ty->format(), + image_ty->access_qualifier()); break; } case Type::kSampledImage: { const SampledImage* image_ty = type.AsSampledImage(); const Type* ele_ty = image_ty->image_type(); - rebuilt_ty = MakeUnique(RebuildType(*ele_ty)); + rebuilt_ty = + MakeUnique(RebuildType(GetId(ele_ty), *ele_ty)); break; } case Type::kArray: { const Array* array_ty = type.AsArray(); - rebuilt_ty = - MakeUnique(array_ty->element_type(), array_ty->length_info()); + const Type* ele_ty = array_ty->element_type(); + rebuilt_ty = MakeUnique(RebuildType(GetId(ele_ty), *ele_ty), + array_ty->length_info()); break; } case Type::kRuntimeArray: { const RuntimeArray* array_ty = type.AsRuntimeArray(); const Type* ele_ty = array_ty->element_type(); - rebuilt_ty = MakeUnique(RebuildType(*ele_ty)); + rebuilt_ty = + MakeUnique(RebuildType(GetId(ele_ty), *ele_ty)); break; } case Type::kStruct: { @@ -594,7 +605,7 @@ Type* TypeManager::RebuildType(const Type& type) { std::vector subtypes; subtypes.reserve(struct_ty->element_types().size()); for (const auto* ele_ty : struct_ty->element_types()) { - subtypes.push_back(RebuildType(*ele_ty)); + subtypes.push_back(RebuildType(GetId(ele_ty), *ele_ty)); } rebuilt_ty = MakeUnique(subtypes); Struct* rebuilt_struct = rebuilt_ty->AsStruct(); @@ -611,7 +622,7 @@ Type* TypeManager::RebuildType(const Type& type) { case Type::kPointer: { const Pointer* pointer_ty = type.AsPointer(); const Type* ele_ty = pointer_ty->pointee_type(); - rebuilt_ty = MakeUnique(RebuildType(*ele_ty), + rebuilt_ty = MakeUnique(RebuildType(GetId(ele_ty), *ele_ty), pointer_ty->storage_class()); break; } @@ -621,9 +632,10 @@ Type* TypeManager::RebuildType(const Type& type) { std::vector param_types; param_types.reserve(function_ty->param_types().size()); for (const auto* param_ty : function_ty->param_types()) { - param_types.push_back(RebuildType(*param_ty)); + param_types.push_back(RebuildType(GetId(param_ty), *param_ty)); } - rebuilt_ty = MakeUnique(RebuildType(*ret_ty), param_types); + rebuilt_ty = MakeUnique(RebuildType(GetId(ret_ty), *ret_ty), + param_types); break; } case Type::kForwardPointer: { @@ -633,7 +645,7 @@ Type* TypeManager::RebuildType(const Type& type) { const Pointer* target_ptr = forward_ptr_ty->target_pointer(); if (target_ptr) { rebuilt_ty->AsForwardPointer()->SetTargetPointer( - RebuildType(*target_ptr)->AsPointer()); + RebuildType(GetId(target_ptr), *target_ptr)->AsPointer()); } break; } @@ -641,16 +653,17 @@ Type* TypeManager::RebuildType(const Type& type) { const CooperativeMatrixNV* cm_type = type.AsCooperativeMatrixNV(); const Type* component_type = cm_type->component_type(); rebuilt_ty = MakeUnique( - RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(), - cm_type->columns_id()); + RebuildType(GetId(component_type), *component_type), + cm_type->scope_id(), cm_type->rows_id(), cm_type->columns_id()); break; } case Type::kCooperativeMatrixKHR: { const CooperativeMatrixKHR* cm_type = type.AsCooperativeMatrixKHR(); const Type* component_type = cm_type->component_type(); rebuilt_ty = MakeUnique( - RebuildType(*component_type), cm_type->scope_id(), cm_type->rows_id(), - cm_type->columns_id(), cm_type->use_id()); + RebuildType(GetId(component_type), *component_type), + cm_type->scope_id(), cm_type->rows_id(), cm_type->columns_id(), + cm_type->use_id()); break; } default: @@ -669,7 +682,7 @@ Type* TypeManager::RebuildType(const Type& type) { void TypeManager::RegisterType(uint32_t id, const Type& type) { // Rebuild |type| so it and all its constituent types are owned by the type // pool. - Type* rebuilt = RebuildType(type); + Type* rebuilt = RebuildType(id, type); assert(rebuilt->IsSame(&type)); id_to_type_[id] = rebuilt; if (GetId(rebuilt) == 0) { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.h b/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.h index a70c371..948b691 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/opt/type_manager.h @@ -260,7 +260,9 @@ class TypeManager { // Returns an equivalent pointer to |type| built in terms of pointers owned by // |type_pool_|. For example, if |type| is a vec3 of bool, it will be rebuilt // replacing the bool subtype with one owned by |type_pool_|. - Type* RebuildType(const Type& type); + // + // The re-built type will have ID |type_id|. + Type* RebuildType(uint32_t type_id, const Type& type); // Completes the incomplete type |type|, by replaces all references to // ForwardPointer by the defining Pointer. diff --git a/libs/bgfx/3rdparty/spirv-tools/source/table.h b/libs/bgfx/3rdparty/spirv-tools/source/table.h index 8097f13..4f1dc1f 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/table.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/table.h @@ -74,7 +74,7 @@ typedef struct spv_ext_inst_desc_t { const uint32_t ext_inst; const uint32_t numCapabilities; const spv::Capability* capabilities; - const spv_operand_type_t operandTypes[16]; // TODO: Smaller/larger? + const spv_operand_type_t operandTypes[40]; // vksp needs at least 40 } spv_ext_inst_desc_t; typedef struct spv_ext_inst_group_t { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/text.cpp b/libs/bgfx/3rdparty/spirv-tools/source/text.cpp index 737c223..fda46ec 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/text.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/text.cpp @@ -227,8 +227,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, // Set the extended instruction type. // The import set id is the 3rd operand of OpExtInst. - if (spv::Op(pInst->opcode) == spv::Op::OpExtInst && - pInst->words.size() == 4) { + if (spvIsExtendedInstruction(pInst->opcode) && pInst->words.size() == 4) { auto ext_inst_type = context->getExtInstTypeForId(pInst->words[3]); if (ext_inst_type == SPV_EXT_INST_TYPE_NONE) { return context->diagnostic() @@ -411,6 +410,7 @@ spv_result_t spvTextEncodeOperand(const spvtools::AssemblyGrammar& grammar, case SPV_OPERAND_TYPE_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_IMAGE: case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS: + case SPV_OPERAND_TYPE_OPTIONAL_RAW_ACCESS_CHAIN_OPERANDS: case SPV_OPERAND_TYPE_SELECTION_CONTROL: case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS: diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/decoration.h b/libs/bgfx/3rdparty/spirv-tools/source/val/decoration.h index 384cc57..77e0f61 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/decoration.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/decoration.h @@ -15,6 +15,7 @@ #ifndef SOURCE_VAL_DECORATION_H_ #define SOURCE_VAL_DECORATION_H_ +#include #include #include #include @@ -55,6 +56,12 @@ namespace val { // params_ = vector { 2 } // struct_member_index_ = 2 // +// Example 4: Decoration for a Builtin: +// OpDecorate %var BuiltIn FragDepth +// dec_type_ = spv::Decoration::BuiltIn +// params_ = vector { FragDepth } +// struct_member_index_ = kInvalidMember +// class Decoration { public: enum { kInvalidMember = -1 }; @@ -68,6 +75,10 @@ class Decoration { spv::Decoration dec_type() const { return dec_type_; } std::vector& params() { return params_; } const std::vector& params() const { return params_; } + spv::BuiltIn builtin() const { + assert(dec_type_ == spv::Decoration::BuiltIn); + return spv::BuiltIn(params_[0]); + } inline bool operator<(const Decoration& rhs) const { // Note: Sort by struct_member_index_ first, then type, so look up can be diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/instruction.h b/libs/bgfx/3rdparty/spirv-tools/source/val/instruction.h index c524bd3..59e8af1 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/instruction.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/instruction.h @@ -22,6 +22,7 @@ #include #include "source/ext_inst.h" +#include "source/opcode.h" #include "source/table.h" #include "spirv-tools/libspirv.h" @@ -87,13 +88,13 @@ class Instruction { } bool IsNonSemantic() const { - return opcode() == spv::Op::OpExtInst && + return spvIsExtendedInstruction(opcode()) && spvExtInstIsNonSemantic(inst_.ext_inst_type); } /// True if this is an OpExtInst for debug info extension. bool IsDebugInfo() const { - return opcode() == spv::Op::OpExtInst && + return spvIsExtendedInstruction(opcode()) && spvExtInstIsDebugInfo(inst_.ext_inst_type); } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate.cpp index ccf26fb..3236807 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate.cpp @@ -144,6 +144,9 @@ spv_result_t ValidateEntryPoints(ValidationState_t& _) { if (auto error = ValidateFloatControls2(_)) { return error; } + if (auto error = ValidateDuplicateExecutionModes(_)) { + return error; + } return SPV_SUCCESS; } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate.h b/libs/bgfx/3rdparty/spirv-tools/source/val/validate.h index 52267c8..78093ce 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate.h +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate.h @@ -94,6 +94,13 @@ spv_result_t ValidateInterfaces(ValidationState_t& _); /// @return SPV_SUCCESS if no errors are found. spv_result_t ValidateFloatControls2(ValidationState_t& _); +/// @brief Validates duplicated execution modes for each entry point. +/// +/// @param[in] _ the validation state of the module +/// +/// @return SPV_SUCCESS if no errors are found. +spv_result_t ValidateDuplicateExecutionModes(ValidationState_t& _); + /// @brief Validates memory instructions /// /// @param[in] _ the validation state of the module diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp index 7e371c2..e6b0042 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_adjacency.cpp @@ -52,6 +52,7 @@ spv_result_t ValidateAdjacency(ValidationState_t& _) { adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID; break; case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: // If it is a debug info instruction, we do not change the status to // allow debug info instructions before OpVariable in a function. // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_annotation.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_annotation.cpp index 106004d..dac3585 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_annotation.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_annotation.cpp @@ -161,7 +161,8 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, spv::Decoration dec, case spv::Decoration::RestrictPointer: case spv::Decoration::AliasedPointer: if (target->opcode() != spv::Op::OpVariable && - target->opcode() != spv::Op::OpFunctionParameter) { + target->opcode() != spv::Op::OpFunctionParameter && + target->opcode() != spv::Op::OpRawAccessChainNV) { return fail(0) << "must be a memory object declaration"; } if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) { diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp index a7e9942..9e307fc 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_builtins.cpp @@ -741,7 +741,7 @@ std::string BuiltInsValidator::GetReferenceDesc( ss << " which is decorated with BuiltIn "; ss << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]); + (uint32_t)decoration.builtin()); if (function_id_) { ss << " in function <" << function_id_ << ">"; if (execution_model != spv::ExecutionModel::Max) { @@ -1170,7 +1170,7 @@ spv_result_t BuiltInsValidator::ValidateNotCalledWithExecutionModel( const char* execution_model_str = _.grammar().lookupOperandName( SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)); const char* built_in_str = _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]); + SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)decoration.builtin()); return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << (vuid < 0 ? std::string("") : _.VkErrorID(vuid)) << comment << " " << GetIdDesc(referenced_inst) << " depends on " @@ -1201,13 +1201,14 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input && storage_class != spv::StorageClass::Output) { - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4190 : 4199; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4190 : 4199; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -1221,7 +1222,8 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4188 : 4197; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4188 : 4197; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " @@ -1247,7 +1249,8 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4189 : 4198; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4189 : 4198; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be " @@ -1266,7 +1269,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) @@ -1274,7 +1277,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit float array. " << message; })) { @@ -1294,7 +1297,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1303,7 +1306,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit float array. " << message; })) { @@ -1315,7 +1318,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( [this, &decoration, &referenced_from_inst]( const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) + (decoration.builtin() == spv::BuiltIn::ClipDistance) ? 4191 : 4200; return _.diag(SPV_ERROR_INVALID_DATA, @@ -1324,7 +1327,7 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit float array. " << message; })) { @@ -1335,8 +1338,9 @@ spv_result_t BuiltInsValidator::ValidateClipOrCullDistanceAtReference( } default: { - uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::ClipDistance) ? 4187 : 4196; + uint32_t vuid = (decoration.builtin() == spv::BuiltIn::ClipDistance) + ? 4187 + : 4196; return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, @@ -2542,7 +2546,7 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -2561,7 +2565,8 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( if (storage_class == spv::StorageClass::Input) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::TessLevelOuter) ? 4391 : 4395; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " @@ -2574,7 +2579,8 @@ spv_result_t BuiltInsValidator::ValidateTessLevelAtReference( if (storage_class == spv::StorageClass::Output) { assert(function_id_ == 0); - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::TessLevelOuter) ? 4392 : 4396; id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind( &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid, "Vulkan spec doesn't allow TessLevelOuter/TessLevelInner to be " @@ -2724,12 +2730,13 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + (decoration.builtin() == spv::BuiltIn::Layer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << "variable needs to be a 32-bit int scalar. " << message; })) { @@ -2741,12 +2748,13 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtDefinition( [this, &decoration, &inst](const std::string& message) -> spv_result_t { uint32_t vuid = - (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::Layer) ? 4276 : 4408; + (decoration.builtin() == spv::BuiltIn::Layer) ? 4276 : 4408; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << "variable needs to be a 32-bit int scalar. " << message; })) { @@ -2763,7 +2771,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -2877,7 +2885,7 @@ spv_result_t BuiltInsValidator::ValidateLayerOrViewportIndexAtReference( spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateF32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2907,7 +2915,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -2951,7 +2959,7 @@ spv_result_t BuiltInsValidator::ValidateFragmentShaderF32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateI32Vec( decoration, inst, 3, [this, &inst, builtin](const std::string& message) -> spv_result_t { @@ -2980,7 +2988,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -3031,7 +3039,7 @@ spv_result_t BuiltInsValidator::ValidateComputeShaderI32Vec3InputAtReference( spv_result_t BuiltInsValidator::ValidateComputeI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " @@ -3065,7 +3073,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -3116,7 +3124,7 @@ spv_result_t BuiltInsValidator::ValidateComputeI32InputAtReference( spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " @@ -3159,7 +3167,7 @@ spv_result_t BuiltInsValidator::ValidateI32InputAtDefinition( spv_result_t BuiltInsValidator::ValidateI32Vec4InputAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (decoration.struct_member_index() != Decoration::kInvalidMember) { return _.diag(SPV_ERROR_INVALID_DATA, &inst) << "BuiltIn " @@ -3247,7 +3255,7 @@ spv_result_t BuiltInsValidator::ValidateWorkgroupSizeAtReference( << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or " << "TaskEXT execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -3273,14 +3281,15 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtDefinition( decoration, inst, [this, &inst, &decoration](const std::string& message) -> spv_result_t { - uint32_t vuid = (spv::BuiltIn(decoration.params()[0]) == spv::BuiltIn::BaseInstance) - ? 4183 - : 4186; + uint32_t vuid = + (decoration.builtin() == spv::BuiltIn::BaseInstance) ? 4183 + : 4186; return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(vuid) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3295,7 +3304,7 @@ spv_result_t BuiltInsValidator::ValidateBaseInstanceOrVertexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -3346,8 +3355,9 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtDefinition( return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(4209) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3362,7 +3372,7 @@ spv_result_t BuiltInsValidator::ValidateDrawIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -3416,8 +3426,9 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtDefinition( return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(4403) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3432,7 +3443,7 @@ spv_result_t BuiltInsValidator::ValidateViewIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -3480,8 +3491,9 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtDefinition( return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(4206) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3496,7 +3508,7 @@ spv_result_t BuiltInsValidator::ValidateDeviceIndexAtReference( const Decoration& decoration, const Instruction& built_in_inst, const Instruction& referenced_inst, const Instruction& referenced_from_inst) { - uint32_t operand = decoration.params()[0]; + uint32_t operand = (uint32_t)decoration.builtin(); if (spvIsVulkanEnv(_.context()->target_env)) { const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -3526,7 +3538,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtDefinition(const De const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateI32( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3553,7 +3565,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -3596,7 +3608,7 @@ spv_result_t BuiltInsValidator::ValidateFragInvocationCountAtReference( spv_result_t BuiltInsValidator::ValidateFragSizeAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateI32Vec( decoration, inst, 2, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3623,7 +3635,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -3666,7 +3678,7 @@ spv_result_t BuiltInsValidator::ValidateFragSizeAtReference( spv_result_t BuiltInsValidator::ValidateFragStencilRefAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateI( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3693,7 +3705,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Output) { @@ -3736,7 +3748,7 @@ spv_result_t BuiltInsValidator::ValidateFragStencilRefAtReference( spv_result_t BuiltInsValidator::ValidateFullyCoveredAtDefinition(const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); if (spv_result_t error = ValidateBool( decoration, inst, [this, &inst, &builtin](const std::string& message) -> spv_result_t { @@ -3763,7 +3775,7 @@ spv_result_t BuiltInsValidator::ValidateFullyCoveredAtReference( const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -3814,8 +3826,9 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtDefinition( << "According to the " << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3839,7 +3852,7 @@ spv_result_t BuiltInsValidator::ValidateNVSMOrARMCoreBuiltinsAtReference( << spvLogStringForEnv(_.context()->target_env) << " spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be only used for " "variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -3868,8 +3881,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtDefinition( return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(4486) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3892,7 +3906,7 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4485) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be only used for variables with Output storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) @@ -3909,8 +3923,9 @@ spv_result_t BuiltInsValidator::ValidatePrimitiveShadingRateAtReference( default: { return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4484) << "Vulkan spec allows BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " to be used only with Vertex, Geometry, or MeshNV " "execution models. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, @@ -3941,8 +3956,9 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtDefinition( return _.diag(SPV_ERROR_INVALID_DATA, &inst) << _.VkErrorID(4492) << "According to the Vulkan spec BuiltIn " - << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + << _.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int scalar. " << message; })) { @@ -3965,7 +3981,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4491) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) @@ -3977,7 +3993,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(4490) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be used only with the Fragment execution model. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -3998,7 +4014,7 @@ spv_result_t BuiltInsValidator::ValidateShadingRateAtReference( spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); switch (builtin) { case spv::BuiltIn::HitTNV: case spv::BuiltIn::RayTminKHR: @@ -4121,7 +4137,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && storage_class != spv::StorageClass::Input) { @@ -4129,7 +4145,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec allows BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be only used for variables with Input storage class. " << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst) @@ -4142,10 +4158,11 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst) << _.VkErrorID(vuid) << "Vulkan spec does not allow BuiltIn " << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, - decoration.params()[0]) + (uint32_t)decoration.builtin()) << " to be used with the execution model " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_EXECUTION_MODEL, uint32_t(execution_model)) + SPV_OPERAND_TYPE_EXECUTION_MODEL, + uint32_t(execution_model)) << ".\n" << GetReferenceDesc(decoration, built_in_inst, referenced_inst, referenced_from_inst, execution_model); @@ -4167,7 +4184,7 @@ spv_result_t BuiltInsValidator::ValidateRayTracingBuiltinsAtReference( spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition( const Decoration& decoration, const Instruction& inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorType); if (builtin == spv::BuiltIn::PrimitivePointIndicesEXT) { if (spv_result_t error = ValidateI32Arr( @@ -4179,7 +4196,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 32-bit int array." << message; })) { @@ -4196,7 +4214,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 2-component 32-bit int " "array." << message; @@ -4214,7 +4233,8 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtDefinition( << spvLogStringForEnv(_.context()->target_env) << " spec BuiltIn " << _.grammar().lookupOperandName( - SPV_OPERAND_TYPE_BUILT_IN, decoration.params()[0]) + SPV_OPERAND_TYPE_BUILT_IN, + (uint32_t)decoration.builtin()) << " variable needs to be a 3-component 32-bit int " "array." << message; @@ -4233,7 +4253,7 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference( const Instruction& referenced_inst, const Instruction& referenced_from_inst) { if (spvIsVulkanEnv(_.context()->target_env)) { - const spv::BuiltIn builtin = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn builtin = decoration.builtin(); const spv::StorageClass storage_class = GetStorageClass(referenced_from_inst); if (storage_class != spv::StorageClass::Max && @@ -4279,7 +4299,7 @@ spv_result_t BuiltInsValidator::ValidateMeshShadingEXTBuiltinsAtReference( spv_result_t BuiltInsValidator::ValidateSingleBuiltInAtDefinition( const Decoration& decoration, const Instruction& inst) { - const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]); + const spv::BuiltIn label = decoration.builtin(); if (!spvIsVulkanEnv(_.context()->target_env)) { // Early return. All currently implemented rules are based on Vulkan spec. diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp index caa4a6f..7364cab 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_decorations.cpp @@ -71,26 +71,6 @@ uint32_t GetArrayStride(uint32_t array_id, ValidationState_t& vstate) { return 0; } -// Returns true if the given variable has a BuiltIn decoration. -bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) { - const auto& decorations = vstate.id_decorations(var_id); - return std::any_of(decorations.begin(), decorations.end(), - [](const Decoration& d) { - return spv::Decoration::BuiltIn == d.dec_type(); - }); -} - -// Returns true if the given structure type has any members with BuiltIn -// decoration. -bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) { - const auto& decorations = vstate.id_decorations(struct_id); - return std::any_of( - decorations.begin(), decorations.end(), [](const Decoration& d) { - return spv::Decoration::BuiltIn == d.dec_type() && - Decoration::kInvalidMember != d.struct_member_index(); - }); -} - // Returns true if the given structure type has a Block decoration. bool isBlock(uint32_t struct_id, ValidationState_t& vstate) { const auto& decorations = vstate.id_decorations(struct_id); @@ -623,6 +603,14 @@ spv_result_t checkLayout(uint32_t struct_id, const char* storage_class_str, seen[next_offset % 16] = true; } + } else if (spv::Op::OpTypeMatrix == element_inst->opcode()) { + // Matrix stride would be on the array element in the struct. + const auto stride = constraint.matrix_stride; + if (!IsAlignedTo(stride, alignment)) { + return fail(memberIdx) + << "is a matrix with stride " << stride + << " not satisfying alignment to " << alignment; + } } // Proceed to the element in case it is an array. @@ -675,7 +663,16 @@ bool checkForRequiredDecoration(uint32_t struct_id, spv::Op type, ValidationState_t& vstate) { const auto& members = getStructMembers(struct_id, vstate); for (size_t memberIdx = 0; memberIdx < members.size(); memberIdx++) { - const auto id = members[memberIdx]; + auto id = members[memberIdx]; + if (type == spv::Op::OpTypeMatrix) { + // Matrix decorations also apply to arrays of matrices. + auto memberInst = vstate.FindDef(id); + while (memberInst->opcode() == spv::Op::OpTypeArray || + memberInst->opcode() == spv::Op::OpTypeRuntimeArray) { + memberInst = vstate.FindDef(memberInst->GetOperandAs(1u)); + } + id = memberInst->id(); + } if (type != vstate.FindDef(id)->opcode()) continue; bool found = false; for (auto& dec : vstate.id_decorations(id)) { @@ -769,6 +766,8 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { int num_workgroup_variables_with_aliased = 0; for (const auto& desc : descs) { std::unordered_set seen_vars; + std::unordered_set input_var_builtin; + std::unordered_set output_var_builtin; for (auto interface : desc.interfaces) { Instruction* var_instr = vstate.FindDef(interface); if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) { @@ -812,33 +811,70 @@ spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) { // to. const uint32_t type_id = ptr_instr->word(3); Instruction* type_instr = vstate.FindDef(type_id); - if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() && - isBuiltInStruct(type_id, vstate)) { - if (!isBlock(type_id, vstate)) { - return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id)) - << vstate.VkErrorID(4919) - << "Interface struct has no Block decoration but has " - "BuiltIn members. " - "Location decorations must be used on each member of " - "OpVariable with a structure type that is a block not " - "decorated with Location."; + const bool is_struct = + type_instr && spv::Op::OpTypeStruct == type_instr->opcode(); + + // Search all Built-in (on the variable or the struct) + bool has_built_in = false; + for (auto& dec : + vstate.id_decorations(is_struct ? type_id : interface)) { + if (dec.dec_type() != spv::Decoration::BuiltIn) continue; + has_built_in = true; + + if (!spvIsVulkanEnv(vstate.context()->target_env)) continue; + + const spv::BuiltIn builtin = dec.builtin(); + if (storage_class == spv::StorageClass::Input) { + if (!input_var_builtin.insert(builtin).second) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << vstate.VkErrorID(9658) + << "OpEntryPoint contains duplicate input variables " + "with " + << vstate.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)builtin) + << " builtin"; + } } - if (storage_class == spv::StorageClass::Input) - ++num_builtin_block_inputs; - if (storage_class == spv::StorageClass::Output) - ++num_builtin_block_outputs; - if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) - break; - if (auto error = CheckBuiltInVariable(interface, vstate)) - return error; - } else if (isBuiltInVar(interface, vstate)) { + if (storage_class == spv::StorageClass::Output) { + if (!output_var_builtin.insert(builtin).second) { + return vstate.diag(SPV_ERROR_INVALID_ID, var_instr) + << vstate.VkErrorID(9659) + << "OpEntryPoint contains duplicate output variables " + "with " + << vstate.grammar().lookupOperandName( + SPV_OPERAND_TYPE_BUILT_IN, (uint32_t)builtin) + << " builtin"; + } + } + } + + if (has_built_in) { if (auto error = CheckBuiltInVariable(interface, vstate)) return error; + + if (is_struct) { + if (!isBlock(type_id, vstate)) { + return vstate.diag(SPV_ERROR_INVALID_DATA, + vstate.FindDef(type_id)) + << vstate.VkErrorID(4919) + << "Interface struct has no Block decoration but has " + "BuiltIn members. " + "Location decorations must be used on each member of " + "OpVariable with a structure type that is a block not " + "decorated with Location."; + } + if (storage_class == spv::StorageClass::Input) + ++num_builtin_block_inputs; + if (storage_class == spv::StorageClass::Output) + ++num_builtin_block_outputs; + if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) + break; + } } if (storage_class == spv::StorageClass::Workgroup) { ++num_workgroup_variables; - if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) { + if (is_struct) { if (hasDecoration(type_id, spv::Decoration::Block, vstate)) ++num_workgroup_variables_with_block; if (hasDecoration(var_instr->id(), spv::Decoration::Aliased, @@ -1325,21 +1361,14 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) { // Returns true if |decoration| cannot be applied to the same id more than once. bool AtMostOncePerId(spv::Decoration decoration) { - return decoration == spv::Decoration::ArrayStride; + return decoration != spv::Decoration::UserSemantic && + decoration != spv::Decoration::FuncParamAttr; } // Returns true if |decoration| cannot be applied to the same member more than // once. bool AtMostOncePerMember(spv::Decoration decoration) { - switch (decoration) { - case spv::Decoration::Offset: - case spv::Decoration::MatrixStride: - case spv::Decoration::RowMajor: - case spv::Decoration::ColMajor: - return true; - default: - return false; - } + return decoration != spv::Decoration::UserSemantic; } spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) { @@ -1556,7 +1585,8 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, const auto opcode = inst.opcode(); const auto type_id = inst.type_id(); if (opcode != spv::Op::OpVariable && - opcode != spv::Op::OpFunctionParameter) { + opcode != spv::Op::OpFunctionParameter && + opcode != spv::Op::OpRawAccessChainNV) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of NonWritable decoration must be a memory object " "declaration (a variable or a function parameter)"; @@ -1569,10 +1599,11 @@ spv_result_t CheckNonWritableDecoration(ValidationState_t& vstate, vstate.features().nonwritable_var_in_function_or_private) { // New permitted feature in SPIR-V 1.4. } else if ( - // It may point to a UBO, SSBO, or storage image. + // It may point to a UBO, SSBO, storage image, or raw access chain. vstate.IsPointerToUniformBlock(type_id) || vstate.IsPointerToStorageBuffer(type_id) || - vstate.IsPointerToStorageImage(type_id)) { + vstate.IsPointerToStorageImage(type_id) || + opcode == spv::Op::OpRawAccessChainNV) { } else { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) << "Target of NonWritable decoration is invalid: must point to a " @@ -1653,6 +1684,7 @@ spv_result_t CheckIntegerWrapDecoration(ValidationState_t& vstate, case spv::Op::OpSNegate: return SPV_SUCCESS; case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: // TODO(dneto): Only certain extended instructions allow these // decorations. For now allow anything. return SPV_SUCCESS; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp index 7b73c9c..05f8ca8 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_extensions.cpp @@ -147,7 +147,7 @@ bool DoesDebugInfoOperandMatchExpectation( 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() != spv::Op::OpExtInst || + if (!spvIsExtendedInstruction(debug_inst->opcode()) || (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) || @@ -165,7 +165,7 @@ bool DoesDebugInfoOperandMatchExpectation( 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() != spv::Op::OpExtInst || + if (!spvIsExtendedInstruction(debug_inst->opcode()) || (debug_inst->ext_inst_type() != SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) || !expectation( @@ -409,7 +409,7 @@ spv_result_t ValidateClspvReflectionArgumentInfo(ValidationState_t& _, spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { const auto decl_id = inst->GetOperandAs(4); const auto decl = _.FindDef(decl_id); - if (!decl || decl->opcode() != spv::Op::OpExtInst) { + if (!decl || !spvIsExtendedInstruction(decl->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "Kernel must be a Kernel extended instruction"; } @@ -432,7 +432,7 @@ spv_result_t ValidateKernelDecl(ValidationState_t& _, const Instruction* inst) { spv_result_t ValidateArgInfo(ValidationState_t& _, const Instruction* inst, uint32_t info_index) { auto info = _.FindDef(inst->GetOperandAs(info_index)); - if (!info || info->opcode() != spv::Op::OpExtInst) { + if (!info || !spvIsExtendedInstruction(info->opcode())) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "ArgInfo must be an ArgumentInfo extended instruction"; } @@ -3706,7 +3706,7 @@ spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) { const spv::Op opcode = inst->opcode(); if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst); if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst); - if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst); + if (spvIsExtendedInstruction(opcode)) return ValidateExtInst(_, inst); return SPV_SUCCESS; } diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_id.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_id.cpp index bcfeb59..2351212 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_id.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_id.cpp @@ -120,15 +120,16 @@ spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) { // instruction operand's ID can be forward referenced. spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { auto can_have_forward_declared_ids = - inst->opcode() == spv::Op::OpExtInst && + spvIsExtendedInstruction(inst->opcode()) && spvExtInstIsDebugInfo(inst->ext_inst_type()) ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction( - inst->ext_inst_type(), inst->word(4)) + inst->opcode(), inst->ext_inst_type(), inst->word(4)) : spvOperandCanBeForwardDeclaredFunction(inst->opcode()); // Keep track of a result id defined by this instruction. 0 means it // does not define an id. uint32_t result_id = 0; + bool has_forward_declared_ids = false; for (unsigned i = 0; i < inst->operands().size(); i++) { const spv_parsed_operand_t& operand = inst->operand(i); @@ -177,6 +178,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) && !spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi && opcode != spv::Op::OpExtInst && + opcode != spv::Op::OpExtInstWithForwardRefsKHR && opcode != spv::Op::OpExtInstImport && opcode != spv::Op::OpSelectionMerge && opcode != spv::Op::OpLoopMerge && @@ -200,6 +202,7 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { ret = SPV_SUCCESS; } } else if (can_have_forward_declared_ids(i)) { + has_forward_declared_ids = true; if (spvOpcodeGeneratesType(inst->opcode()) && !_.IsForwardPointer(operand_word)) { ret = _.diag(SPV_ERROR_INVALID_ID, inst) @@ -229,12 +232,35 @@ spv_result_t IdPass(ValidationState_t& _, Instruction* inst) { << " has not been defined"; } break; + case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: + // Ideally, this check would live in validate_extensions.cpp. But since + // forward references are only allowed on non-semantic instructions, and + // ID validation is done first, we would fail with a "ID had not been + // defined" error before we could give a more helpful message. For this + // reason, this test is done here, so we can be more helpful to the + // user. + if (inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR && + !inst->IsNonSemantic()) + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "OpExtInstWithForwardRefsKHR is only allowed with " + "non-semantic instructions."; + ret = SPV_SUCCESS; + break; default: ret = SPV_SUCCESS; break; } if (SPV_SUCCESS != ret) return ret; } + const bool must_have_forward_declared_ids = + inst->opcode() == spv::Op::OpExtInstWithForwardRefsKHR; + if (must_have_forward_declared_ids && !has_forward_declared_ids) { + return _.diag(SPV_ERROR_INVALID_ID, inst) + << "Opcode OpExtInstWithForwardRefsKHR must have at least one " + "forward " + "declared ID."; + } + if (result_id) _.RemoveIfForwardDeclared(result_id); return SPV_SUCCESS; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_image.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_image.cpp index 543f345..fc1e4a2 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_image.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_image.cpp @@ -914,7 +914,15 @@ spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) { if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) { return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0"; + << _.VkErrorID(6214) + << "Dim SubpassData requires Arrayed to be 0 in the Vulkan " + "environment"; + } + + if (info.dim == spv::Dim::Rect) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(9638) + << "Dim must not be Rect in the Vulkan environment"; } } @@ -982,6 +990,10 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { case spv::Op::OpImageBoxFilterQCOM: case spv::Op::OpImageBlockMatchSSDQCOM: case spv::Op::OpImageBlockMatchSADQCOM: + case spv::Op::OpImageBlockMatchWindowSADQCOM: + case spv::Op::OpImageBlockMatchWindowSSDQCOM: + case spv::Op::OpImageBlockMatchGatherSADQCOM: + case spv::Op::OpImageBlockMatchGatherSSDQCOM: return true; case spv::Op::OpStore: if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true; @@ -993,7 +1005,8 @@ bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) { spv_result_t ValidateSampledImage(ValidationState_t& _, const Instruction* inst) { - if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) { + auto type_inst = _.FindDef(inst->type_id()); + if (type_inst->opcode() != spv::Op::OpTypeSampledImage) { return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Expected Result Type to be OpTypeSampledImage."; } @@ -1004,6 +1017,11 @@ spv_result_t ValidateSampledImage(ValidationState_t& _, << "Expected Image to be of type OpTypeImage."; } + if (type_inst->GetOperandAs(1) != image_type) { +// return _.diag(SPV_ERROR_INVALID_DATA, inst) +// << "Expected Image to have the same type as Result Type Image"; + } + ImageTypeInfo info; if (!GetImageTypeInfo(_, image_type, &info)) { return _.diag(SPV_ERROR_INVALID_DATA, inst) @@ -2157,7 +2175,8 @@ spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id, spv::Decoration decor) { const Instruction* si_inst = nullptr; const Instruction* ld_inst = _.FindDef(id); - if (ld_inst->opcode() == spv::Op::OpSampledImage) { + bool is_intf_obj = (ld_inst->opcode() == spv::Op::OpSampledImage); + if (is_intf_obj == true) { si_inst = ld_inst; int t_idx = si_inst->GetOperandAs(2); // texture ld_inst = _.FindDef(t_idx); @@ -2168,7 +2187,57 @@ spv_result_t ValidateImageProcessingQCOMDecoration(ValidationState_t& _, int id, int texture_id = ld_inst->GetOperandAs(2); // variable to load if (!_.HasDecoration(texture_id, decor)) { return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) - << "Missing decoration WeightTextureQCOM/BlockMatchTextureQCOM"; + << "Missing decoration " << _.SpvDecorationString(decor); + } + + return SPV_SUCCESS; +} + +spv_result_t ValidateImageProcessing2QCOMWindowDecoration(ValidationState_t& _, + int id) { + const Instruction* ld_inst = _.FindDef(id); + bool is_intf_obj = (ld_inst->opcode() != spv::Op::OpSampledImage); + if (is_intf_obj == true) { + if (ld_inst->opcode() != spv::Op::OpLoad) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) << "Expect to see OpLoad"; + } + int texture_id = ld_inst->GetOperandAs(2); // variable to load + spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM; + if (!_.HasDecoration(texture_id, decor)) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) + << "Missing decoration " << _.SpvDecorationString(decor); + } + decor = spv::Decoration::BlockMatchSamplerQCOM; + if (!_.HasDecoration(texture_id, decor)) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) + << "Missing decoration " << _.SpvDecorationString(decor); + } + } else { + const Instruction* si_inst = ld_inst; + int t_idx = si_inst->GetOperandAs(2); // texture + const Instruction* t_ld_inst = _.FindDef(t_idx); + if (t_ld_inst->opcode() != spv::Op::OpLoad) { + return _.diag(SPV_ERROR_INVALID_DATA, t_ld_inst) + << "Expect to see OpLoad"; + } + int texture_id = t_ld_inst->GetOperandAs(2); // variable to load + spv::Decoration decor = spv::Decoration::BlockMatchTextureQCOM; + if (!_.HasDecoration(texture_id, decor)) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) + << "Missing decoration " << _.SpvDecorationString(decor); + } + int s_idx = si_inst->GetOperandAs(3); // sampler + const Instruction* s_ld_inst = _.FindDef(s_idx); + if (s_ld_inst->opcode() != spv::Op::OpLoad) { + return _.diag(SPV_ERROR_INVALID_DATA, s_ld_inst) + << "Expect to see OpLoad"; + } + int sampler_id = s_ld_inst->GetOperandAs(2); // variable to load + decor = spv::Decoration::BlockMatchSamplerQCOM; + if (!_.HasDecoration(sampler_id, decor)) { + return _.diag(SPV_ERROR_INVALID_DATA, ld_inst) + << "Missing decoration " << _.SpvDecorationString(decor); + } } return SPV_SUCCESS; @@ -2196,6 +2265,26 @@ spv_result_t ValidateImageProcessingQCOM(ValidationState_t& _, _, ref_idx, spv::Decoration::BlockMatchTextureQCOM); break; } + case spv::Op::OpImageBlockMatchWindowSSDQCOM: + case spv::Op::OpImageBlockMatchWindowSADQCOM: { + int tgt_idx = inst->GetOperandAs(2); // target + res = ValidateImageProcessing2QCOMWindowDecoration(_, tgt_idx); + if (res != SPV_SUCCESS) break; + int ref_idx = inst->GetOperandAs(4); // reference + res = ValidateImageProcessing2QCOMWindowDecoration(_, ref_idx); + break; + } + case spv::Op::OpImageBlockMatchGatherSSDQCOM: + case spv::Op::OpImageBlockMatchGatherSADQCOM: { + int tgt_idx = inst->GetOperandAs(2); // target + res = ValidateImageProcessingQCOMDecoration( + _, tgt_idx, spv::Decoration::BlockMatchTextureQCOM); + if (res != SPV_SUCCESS) break; + int ref_idx = inst->GetOperandAs(4); // reference + res = ValidateImageProcessingQCOMDecoration( + _, ref_idx, spv::Decoration::BlockMatchTextureQCOM); + break; + } default: break; } @@ -2326,6 +2415,10 @@ spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) { case spv::Op::OpImageBoxFilterQCOM: case spv::Op::OpImageBlockMatchSSDQCOM: case spv::Op::OpImageBlockMatchSADQCOM: + case spv::Op::OpImageBlockMatchWindowSADQCOM: + case spv::Op::OpImageBlockMatchWindowSSDQCOM: + case spv::Op::OpImageBlockMatchGatherSADQCOM: + case spv::Op::OpImageBlockMatchGatherSSDQCOM: return ValidateImageProcessingQCOM(_, inst); default: @@ -2378,6 +2471,10 @@ bool IsImageInstruction(const spv::Op opcode) { case spv::Op::OpImageBoxFilterQCOM: case spv::Op::OpImageBlockMatchSSDQCOM: case spv::Op::OpImageBlockMatchSADQCOM: + case spv::Op::OpImageBlockMatchWindowSADQCOM: + case spv::Op::OpImageBlockMatchWindowSSDQCOM: + case spv::Op::OpImageBlockMatchGatherSADQCOM: + case spv::Op::OpImageBlockMatchGatherSSDQCOM: return true; default: break; @@ -2396,6 +2493,11 @@ spv_result_t ValidateQCOMImageProcessingTextureUsages(ValidationState_t& _, case spv::Op::OpImageBlockMatchSSDQCOM: case spv::Op::OpImageBlockMatchSADQCOM: break; + case spv::Op::OpImageBlockMatchWindowSADQCOM: + case spv::Op::OpImageBlockMatchWindowSSDQCOM: + case spv::Op::OpImageBlockMatchGatherSADQCOM: + case spv::Op::OpImageBlockMatchGatherSSDQCOM: + break; default: for (size_t i = 0; i < inst->operands().size(); ++i) { int id = inst->GetOperandAs(i); diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp index 54ebfd7..8f10b9d 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_interfaces.cpp @@ -254,37 +254,24 @@ spv_result_t GetLocationsForVariable( // equal. Also track Patch and PerTaskNV decorations. bool has_location = false; uint32_t location = 0; - bool has_component = false; uint32_t component = 0; bool has_index = false; uint32_t index = 0; bool has_patch = false; bool has_per_task_nv = false; bool has_per_vertex_khr = false; + // Duplicate Location, Component, Index are checked elsewhere. for (auto& dec : _.id_decorations(variable->id())) { if (dec.dec_type() == spv::Decoration::Location) { - if (has_location && dec.params()[0] != location) { - return _.diag(SPV_ERROR_INVALID_DATA, variable) - << "Variable has conflicting location decorations"; - } has_location = true; location = dec.params()[0]; } else if (dec.dec_type() == spv::Decoration::Component) { - if (has_component && dec.params()[0] != component) { - return _.diag(SPV_ERROR_INVALID_DATA, variable) - << "Variable has conflicting component decorations"; - } - has_component = true; component = dec.params()[0]; } else if (dec.dec_type() == spv::Decoration::Index) { if (!is_output || !is_fragment) { return _.diag(SPV_ERROR_INVALID_DATA, variable) << "Index can only be applied to Fragment output variables"; } - if (has_index && dec.params()[0] != index) { - return _.diag(SPV_ERROR_INVALID_DATA, variable) - << "Variable has conflicting index decorations"; - } has_index = true; index = dec.params()[0]; } else if (dec.dec_type() == spv::Decoration::BuiltIn) { @@ -532,6 +519,8 @@ 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 patch_locations_index0; + std::unordered_set patch_locations_index1; std::unordered_set seen; for (uint32_t i = 3; i < entry_point->operands().size(); ++i) { auto interface_id = entry_point->GetOperandAs(i); @@ -547,6 +536,26 @@ spv_result_t ValidateLocations(ValidationState_t& _, continue; } + // The two Tessellation stages have a "Patch" variable that interface with + // the Location mechanism, but are not suppose to be tied to the "normal" + // input/output Location. + // TODO - SPIR-V allows the Patch decoration to be applied to struct + // members, but is not allowed in GLSL/HLSL + bool has_patch = false; + for (auto& dec : _.id_decorations(interface_var->id())) { + if (dec.dec_type() == spv::Decoration::Patch) { + has_patch = true; + if (auto error = GetLocationsForVariable(_, entry_point, interface_var, + &patch_locations_index0, + &patch_locations_index1)) + return error; + break; + } + } + if (has_patch) { + continue; + } + auto locations = (storage_class == spv::StorageClass::Input) ? &input_locations : &output_locations_index0; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp index dbc1f1e..05a8675 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_layout.cpp @@ -35,6 +35,7 @@ spv_result_t ModuleScopedInstructions(ValidationState_t& _, const Instruction* inst, spv::Op opcode) { switch (opcode) { case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; @@ -243,6 +244,7 @@ spv_result_t FunctionScopedInstructions(ValidationState_t& _, break; case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: if (spvExtInstIsDebugInfo(inst->ext_inst_type())) { const uint32_t ext_inst_index = inst->word(4); bool local_debug_info = false; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp index 41dd71e..ef6676f 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_memory.cpp @@ -349,7 +349,8 @@ spv_result_t CheckMemoryAccess(ValidationState_t& _, const Instruction* inst, if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) { if (inst->opcode() == spv::Op::OpStore || - inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV) { + inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV || + inst->opcode() == spv::Op::OpCooperativeMatrixStoreKHR) { return _.diag(SPV_ERROR_INVALID_ID, inst) << "MakePointerVisibleKHR cannot be used with OpStore."; } @@ -1386,10 +1387,10 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, // should be less than the number of struct members. const int64_t num_struct_members = static_cast(type_pointee->words().size() - 2); - if (cur_index >= num_struct_members) { + if (cur_index >= num_struct_members || cur_index < 0) { return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr) << "Index is out of bounds: " << instr_name - << " can not find index " << cur_index + << " cannot find index " << cur_index << " into the structure " << _.getIdName(type_pointee->id()) << ". This structure has " << num_struct_members << " members. Largest valid index is " @@ -1410,7 +1411,7 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, } } } - // At this point, we have fully walked down from the base using the indeces. + // At this point, we have fully walked down from the base using the indices. // The type being pointed to should be the same as the result type. if (type_pointee->id() != result_type_pointee->id()) { return _.diag(SPV_ERROR_INVALID_ID, inst) @@ -1427,6 +1428,126 @@ spv_result_t ValidateAccessChain(ValidationState_t& _, return SPV_SUCCESS; } +spv_result_t ValidateRawAccessChain(ValidationState_t& _, + const Instruction* inst) { + std::string instr_name = "Op" + std::string(spvOpcodeString(inst->opcode())); + + // The result type must be OpTypePointer. + const auto result_type = _.FindDef(inst->type_id()); + if (spv::Op::OpTypePointer != result_type->opcode()) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Result Type of " << instr_name << " " + << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op" + << spvOpcodeString(result_type->opcode()) << '.'; + } + + // The pointed storage class must be valid. + const auto storage_class = result_type->GetOperandAs(1); + if (storage_class != spv::StorageClass::StorageBuffer && + storage_class != spv::StorageClass::PhysicalStorageBuffer && + storage_class != spv::StorageClass::Uniform) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Result Type of " << instr_name << " " + << _.getIdName(inst->id()) + << " must point to a storage class of " + "StorageBuffer, PhysicalStorageBuffer, or Uniform."; + } + + // The pointed type must not be one in the list below. + const auto result_type_pointee = + _.FindDef(result_type->GetOperandAs(2)); + if (result_type_pointee->opcode() == spv::Op::OpTypeArray || + result_type_pointee->opcode() == spv::Op::OpTypeMatrix || + result_type_pointee->opcode() == spv::Op::OpTypeStruct) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Result Type of " << instr_name << " " + << _.getIdName(inst->id()) + << " must not point to " + "OpTypeArray, OpTypeMatrix, or OpTypeStruct."; + } + + // Validate Stride is a OpConstant. + const auto stride = _.FindDef(inst->GetOperandAs(3)); + if (stride->opcode() != spv::Op::OpConstant) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The Stride of " << instr_name << " " + << _.getIdName(inst->id()) << " must be OpConstant. Found Op" + << spvOpcodeString(stride->opcode()) << '.'; + } + // Stride type must be OpTypeInt + const auto stride_type = _.FindDef(stride->type_id()); + if (stride_type->opcode() != spv::Op::OpTypeInt) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of Stride of " << instr_name << " " + << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op" + << spvOpcodeString(stride_type->opcode()) << '.'; + } + + // Index and Offset type must be OpTypeInt with a width of 32 + const auto ValidateType = [&](const char* name, + int operandIndex) -> spv_result_t { + const auto value = _.FindDef(inst->GetOperandAs(operandIndex)); + const auto value_type = _.FindDef(value->type_id()); + if (value_type->opcode() != spv::Op::OpTypeInt) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The type of " << name << " of " << instr_name << " " + << _.getIdName(inst->id()) << " must be OpTypeInt. Found Op" + << spvOpcodeString(value_type->opcode()) << '.'; + } + const auto width = value_type->GetOperandAs(1); + if (width != 32) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "The integer width of " << name << " of " << instr_name + << " " << _.getIdName(inst->id()) << " must be 32. Found " + << width << '.'; + } + return SPV_SUCCESS; + }; + spv_result_t result; + result = ValidateType("Index", 4); + if (result != SPV_SUCCESS) { + return result; + } + result = ValidateType("Offset", 5); + if (result != SPV_SUCCESS) { + return result; + } + + uint32_t access_operands = 0; + if (inst->operands().size() >= 7) { + access_operands = inst->GetOperandAs(6); + } + if (access_operands & + uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) { + uint64_t stride_value = 0; + if (_.EvalConstantValUint64(stride->id(), &stride_value) && + stride_value == 0) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Stride must not be zero when per-element robustness is used."; + } + } + if (access_operands & + uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) || + access_operands & + uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) { + if (storage_class == spv::StorageClass::PhysicalStorageBuffer) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Storage class cannot be PhysicalStorageBuffer when " + "raw access chain robustness is used."; + } + } + if (access_operands & + uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerComponentNV) && + access_operands & + uint32_t(spv::RawAccessChainOperandsMask::RobustnessPerElementNV)) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Per-component robustness and per-element robustness are " + "mutually exclusive."; + } + + return SPV_SUCCESS; +} + spv_result_t ValidatePtrAccessChain(ValidationState_t& _, const Instruction* inst) { if (_.addressing_model() == spv::AddressingModel::Logical) { @@ -1866,6 +1987,9 @@ spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) { case spv::Op::OpInBoundsPtrAccessChain: if (auto error = ValidateAccessChain(_, inst)) return error; break; + case spv::Op::OpRawAccessChainNV: + if (auto error = ValidateRawAccessChain(_, inst)) return error; + break; case spv::Op::OpArrayLength: if (auto error = ValidateArrayLength(_, inst)) return error; break; diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_misc.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_misc.cpp index d71fd2d..a404134 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_misc.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_misc.cpp @@ -50,10 +50,22 @@ spv_result_t ValidateShaderClock(ValidationState_t& _, bool is_int32 = false, is_const_int32 = false; uint32_t value = 0; std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope); - if (is_const_int32 && spv::Scope(value) != spv::Scope::Subgroup && - spv::Scope(value) != spv::Scope::Device) { - return _.diag(SPV_ERROR_INVALID_DATA, inst) - << _.VkErrorID(4652) << "Scope must be Subgroup or Device"; + if (is_const_int32) { + spv::Scope scope_val{value}; + if (spvIsVulkanEnv(_.context()->target_env)) { + if (scope_val != spv::Scope::Subgroup && + scope_val != spv::Scope::Device) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << _.VkErrorID(4652) << "Scope must be Subgroup or Device"; + } + } else if (spvIsOpenCLEnv(_.context()->target_env)) { + if (scope_val != spv::Scope::Workgroup && + scope_val != spv::Scope::Subgroup && + scope_val != spv::Scope::Device) { + return _.diag(SPV_ERROR_INVALID_DATA, inst) + << "Scope must be Subgroup, Workgroup, or Device"; + } + } } // Result Type must be a 64 - bit unsigned integer type or diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp index 82c6c3f..8502fda 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validate_mode_setting.cpp @@ -346,6 +346,7 @@ spv_result_t ValidateExecutionMode(ValidationState_t& _, case spv::ExecutionMode::LocalSizeHintId: case spv::ExecutionMode::LocalSizeId: case spv::ExecutionMode::FPFastMathDefault: + case spv::ExecutionMode::MaximumRegistersIdINTEL: valid_mode = true; break; default: @@ -723,6 +724,25 @@ spv_result_t ValidateMemoryModel(ValidationState_t& _, return SPV_SUCCESS; } +bool PerEntryExecutionMode(spv::ExecutionMode mode) { + switch (mode) { + // These execution modes can be specified multiple times per entry point. + case spv::ExecutionMode::DenormPreserve: + case spv::ExecutionMode::DenormFlushToZero: + case spv::ExecutionMode::SignedZeroInfNanPreserve: + case spv::ExecutionMode::RoundingModeRTE: + case spv::ExecutionMode::RoundingModeRTZ: + case spv::ExecutionMode::FPFastMathDefault: + case spv::ExecutionMode::RoundingModeRTPINTEL: + case spv::ExecutionMode::RoundingModeRTNINTEL: + case spv::ExecutionMode::FloatingPointModeALTINTEL: + case spv::ExecutionMode::FloatingPointModeIEEEINTEL: + return false; + default: + return true; + } +} + } // namespace spv_result_t ValidateFloatControls2(ValidationState_t& _) { @@ -807,5 +827,52 @@ spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) { return SPV_SUCCESS; } +spv_result_t ValidateDuplicateExecutionModes(ValidationState_t& _) { + using PerEntryKey = std::tuple; + using PerOperandKey = std::tuple; + std::set seen_per_entry; + std::set seen_per_operand; + + const auto lookupMode = [&_](spv::ExecutionMode mode) -> std::string { + spv_operand_desc desc = nullptr; + if (_.grammar().lookupOperand(SPV_OPERAND_TYPE_EXECUTION_MODE, + static_cast(mode), + &desc) == SPV_SUCCESS) { + return std::string(desc->name); + } + return "Unknown"; + }; + + for (const auto& inst : _.ordered_instructions()) { + if (inst.opcode() != spv::Op::OpExecutionMode && + inst.opcode() != spv::Op::OpExecutionModeId) { + continue; + } + + const auto entry = inst.GetOperandAs(0); + const auto mode = inst.GetOperandAs(1); + if (PerEntryExecutionMode(mode)) { + if (!seen_per_entry.insert(std::make_tuple(mode, entry)).second) { + return _.diag(SPV_ERROR_INVALID_ID, &inst) + << lookupMode(mode) + << " execution mode must not be specified multiple times per " + "entry point"; + } + } else { + // Execution modes allowed multiple times all take a single operand. + const auto operand = inst.GetOperandAs(2); + if (!seen_per_operand.insert(std::make_tuple(mode, entry, operand)) + .second) { + return _.diag(SPV_ERROR_INVALID_ID, &inst) + << lookupMode(mode) + << " execution mode must not be specified multiple times for " + "the same entry point and operands"; + } + } + } + + return SPV_SUCCESS; +} + } // namespace val } // namespace spvtools diff --git a/libs/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp b/libs/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp index fa5ae3e..b5ed65f 100644 --- a/libs/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp +++ b/libs/bgfx/3rdparty/spirv-tools/source/val/validation_state.cpp @@ -76,6 +76,7 @@ ModuleLayoutSection InstructionLayoutSection( if (current_section == kLayoutTypes) return kLayoutTypes; return kLayoutFunctionDefinitions; case spv::Op::OpExtInst: + case spv::Op::OpExtInstWithForwardRefsKHR: // spv::Op::OpExtInst is only allowed in types section for certain // extended instruction sets. This will be checked separately. if (current_section == kLayoutTypes) return kLayoutTypes; @@ -615,7 +616,8 @@ void ValidationState_t::RegisterQCOMImageProcessingTextureConsumer( uint32_t texture_id, const Instruction* consumer0, const Instruction* consumer1) { if (HasDecoration(texture_id, spv::Decoration::WeightTextureQCOM) || - HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM)) { + HasDecoration(texture_id, spv::Decoration::BlockMatchTextureQCOM) || + HasDecoration(texture_id, spv::Decoration::BlockMatchSamplerQCOM)) { qcom_image_processing_consumers_.insert(consumer0->id()); if (consumer1) { qcom_image_processing_consumers_.insert(consumer1->id()); @@ -2350,6 +2352,12 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-08722); case 8973: return VUID_WRAP(VUID-StandaloneSpirv-Pointer-08973); + case 9638: + return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-09638); + case 9658: + return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09658); + case 9659: + return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-09659); default: return ""; // unknown id } diff --git a/libs/bgfx/examples/common/imgui/imgui.cpp b/libs/bgfx/examples/common/imgui/imgui.cpp index 47b8533..4b78865 100644 --- a/libs/bgfx/examples/common/imgui/imgui.cpp +++ b/libs/bgfx/examples/common/imgui/imgui.cpp @@ -3,6 +3,9 @@ * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE */ +// TODO: [ZBGFX]: remove all unused stuff +// TODO: [ZBGFX]: rewrite this to zig + #include #include #include @@ -57,9 +60,6 @@ struct OcornutImguiContext const ImVec2 clipPos = _drawData->DisplayPos; // (0,0) unless using multi-viewports const ImVec2 clipScale = _drawData->FramebufferScale; // (1,1) unless using retina display which are often (2,2) - - bgfx::Encoder *encoder = bgfx::begin(); - // Render command lists for (int32_t ii = 0, num = _drawData->CmdListsCount; ii < num; ++ii) { @@ -85,7 +85,7 @@ struct OcornutImguiContext ImDrawIdx *indices = (ImDrawIdx *)tib.data; bx::memCopy(indices, drawList->IdxBuffer.begin(), numIndices * sizeof(ImDrawIdx)); - + bgfx::Encoder *encoder = bgfx::begin(); for (const ImDrawCmd *cmd = drawList->CmdBuffer.begin(), *cmdEnd = drawList->CmdBuffer.end(); cmd != cmdEnd; ++cmd) { if (cmd->UserCallback) @@ -148,9 +148,8 @@ struct OcornutImguiContext } } } - + bgfx::end(encoder); } - bgfx::end(encoder); } void create(float _fontSize, bx::AllocatorI *_allocator) diff --git a/libs/bgfx/include/bgfx/bgfx.h b/libs/bgfx/include/bgfx/bgfx.h index 49cf069..8b0f0ed 100644 --- a/libs/bgfx/include/bgfx/bgfx.h +++ b/libs/bgfx/include/bgfx/bgfx.h @@ -3070,7 +3070,8 @@ namespace bgfx /// @param[in] _width Texture width. /// @param[in] _height Texture height. /// @param[in] _format Texture format. See: `TextureFormat::Enum`. - /// @param[in] _textureFlags Default texture sampling mode is linear, and wrap mode + /// @param[in] _textureFlags Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) + /// flags. Default texture sampling mode is linear, and wrap mode /// is repeat. /// - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap /// mode. @@ -3094,7 +3095,8 @@ namespace bgfx /// @param[in] _ratio Frame buffer size in respect to back-buffer size. See: /// `BackbufferRatio::Enum`. /// @param[in] _format Texture format. See: `TextureFormat::Enum`. - /// @param[in] _textureFlags Default texture sampling mode is linear, and wrap mode + /// @param[in] _textureFlags Texture creation (see `BGFX_TEXTURE_*`.), and sampler (see `BGFX_SAMPLER_*`) + /// flags. Default texture sampling mode is linear, and wrap mode /// is repeat. /// - `BGFX_SAMPLER_[U/V/W]_[MIRROR/CLAMP]` - Mirror or clamp to edge wrap /// mode. diff --git a/libs/bgfx/include/bgfx/defines.h b/libs/bgfx/include/bgfx/defines.h index abf552e..ce3830f 100644 --- a/libs/bgfx/include/bgfx/defines.h +++ b/libs/bgfx/include/bgfx/defines.h @@ -15,7 +15,7 @@ #ifndef BGFX_DEFINES_H_HEADER_GUARD #define BGFX_DEFINES_H_HEADER_GUARD -#define BGFX_API_VERSION UINT32_C(127) +#define BGFX_API_VERSION UINT32_C(128) /** * Color RGB/alpha/depth write. When it's not specified write will be disabled. @@ -467,32 +467,32 @@ #define BGFX_CAPS_COMPUTE UINT64_C(0x0000000000000004) //!< Compute shaders are supported. #define BGFX_CAPS_CONSERVATIVE_RASTER UINT64_C(0x0000000000000008) //!< Conservative rasterization is supported. #define BGFX_CAPS_DRAW_INDIRECT UINT64_C(0x0000000000000010) //!< Draw indirect is supported. -#define BGFX_CAPS_FRAGMENT_DEPTH UINT64_C(0x0000000000000020) //!< Fragment depth is available in fragment shader. -#define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000040) //!< Fragment ordering is available in fragment shader. -#define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000080) //!< Graphics debugger is present. -#define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000100) //!< HDR10 rendering is supported. -#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000200) //!< HiDPI rendering is supported. -#define BGFX_CAPS_IMAGE_RW UINT64_C(0x0000000000000400) //!< Image Read/Write is supported. -#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000000800) //!< 32-bit indices are supported. -#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000001000) //!< Instancing is supported. -#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000002000) //!< Occlusion query is supported. -#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000004000) //!< Renderer is on separate thread. -#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000008000) //!< Multiple windows are supported. -#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000000010000) //!< 2D texture array is supported. -#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000000020000) //!< 3D textures are supported. +#define BGFX_CAPS_DRAW_INDIRECT_COUNT UINT64_C(0x0000000000000020) //!< Draw indirect with indirect count is supported. +#define BGFX_CAPS_FRAGMENT_DEPTH UINT64_C(0x0000000000000040) //!< Fragment depth is available in fragment shader. +#define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000080) //!< Fragment ordering is available in fragment shader. +#define BGFX_CAPS_GRAPHICS_DEBUGGER UINT64_C(0x0000000000000100) //!< Graphics debugger is present. +#define BGFX_CAPS_HDR10 UINT64_C(0x0000000000000200) //!< HDR10 rendering is supported. +#define BGFX_CAPS_HIDPI UINT64_C(0x0000000000000400) //!< HiDPI rendering is supported. +#define BGFX_CAPS_IMAGE_RW UINT64_C(0x0000000000000800) //!< Image Read/Write is supported. +#define BGFX_CAPS_INDEX32 UINT64_C(0x0000000000001000) //!< 32-bit indices are supported. +#define BGFX_CAPS_INSTANCING UINT64_C(0x0000000000002000) //!< Instancing is supported. +#define BGFX_CAPS_OCCLUSION_QUERY UINT64_C(0x0000000000004000) //!< Occlusion query is supported. +#define BGFX_CAPS_PRIMITIVE_ID UINT64_C(0x0000000000008000) //!< PrimitiveID is available in fragment shader. +#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000010000) //!< Renderer is on separate thread. +#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000020000) //!< Multiple windows are supported. #define BGFX_CAPS_TEXTURE_BLIT UINT64_C(0x0000000000040000) //!< Texture blit is supported. -#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000000080000) //!< Transparent back buffer supported. +#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000080000) //!< Texture compare less equal mode is supported. #define BGFX_CAPS_TEXTURE_COMPARE_RESERVED UINT64_C(0x0000000000100000) -#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000200000) //!< Texture compare less equal mode is supported. -#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000400000) //!< Cubemap texture array is supported. -#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000800000) //!< CPU direct access to GPU texture memory. -#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000001000000) //!< Read-back texture is supported. -#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000002000000) //!< Vertex attribute half-float is supported. -#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000004000000) //!< Vertex attribute 10_10_10_2 is supported. -#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000008000000) //!< Rendering with VertexID only is supported. -#define BGFX_CAPS_PRIMITIVE_ID UINT64_C(0x0000000010000000) //!< PrimitiveID is available in fragment shader. -#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000020000000) //!< Viewport layer is available in vertex shader. -#define BGFX_CAPS_DRAW_INDIRECT_COUNT UINT64_C(0x0000000040000000) //!< Draw indirect with indirect count is supported. +#define BGFX_CAPS_TEXTURE_CUBE_ARRAY UINT64_C(0x0000000000200000) //!< Cubemap texture array is supported. +#define BGFX_CAPS_TEXTURE_DIRECT_ACCESS UINT64_C(0x0000000000400000) //!< CPU direct access to GPU texture memory. +#define BGFX_CAPS_TEXTURE_READ_BACK UINT64_C(0x0000000000800000) //!< Read-back texture is supported. +#define BGFX_CAPS_TEXTURE_2D_ARRAY UINT64_C(0x0000000001000000) //!< 2D texture array is supported. +#define BGFX_CAPS_TEXTURE_3D UINT64_C(0x0000000002000000) //!< 3D textures are supported. +#define BGFX_CAPS_TRANSPARENT_BACKBUFFER UINT64_C(0x0000000004000000) //!< Transparent back buffer supported. +#define BGFX_CAPS_VERTEX_ATTRIB_HALF UINT64_C(0x0000000008000000) //!< Vertex attribute half-float is supported. +#define BGFX_CAPS_VERTEX_ATTRIB_UINT10 UINT64_C(0x0000000010000000) //!< Vertex attribute 10_10_10_2 is supported. +#define BGFX_CAPS_VERTEX_ID UINT64_C(0x0000000020000000) //!< Rendering with VertexID only is supported. +#define BGFX_CAPS_VIEWPORT_LAYER_ARRAY UINT64_C(0x0000000040000000) //!< Viewport layer is available in vertex shader. /// All texture compare modes are supported. #define BGFX_CAPS_TEXTURE_COMPARE_ALL (0 \ | BGFX_CAPS_TEXTURE_COMPARE_RESERVED \ diff --git a/libs/bgfx/include/bgfx/embedded_shader.h b/libs/bgfx/include/bgfx/embedded_shader.h index 2884f41..db80f93 100644 --- a/libs/bgfx/include/bgfx/embedded_shader.h +++ b/libs/bgfx/include/bgfx/embedded_shader.h @@ -6,8 +6,8 @@ #ifndef BGFX_EMBEDDED_SHADER_H_HEADER_GUARD #define BGFX_EMBEDDED_SHADER_H_HEADER_GUARD -#include #include "bgfx.h" +#include #define BGFX_EMBEDDED_SHADER_DXBC(...) #define BGFX_EMBEDDED_SHADER_PSSL(...) @@ -34,6 +34,7 @@ || BX_PLATFORM_LINUX \ || BX_PLATFORM_OSX \ || BX_PLATFORM_RPI \ + || BX_PLATFORM_VISIONOS \ || BX_PLATFORM_WINDOWS \ ) #define BGFX_PLATFORM_SUPPORTS_GLSL (0 \ @@ -44,6 +45,7 @@ #define BGFX_PLATFORM_SUPPORTS_METAL (0 \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ + || BX_PLATFORM_VISIONOS \ ) #define BGFX_PLATFORM_SUPPORTS_NVN (0 \ || BX_PLATFORM_NX \ @@ -54,42 +56,50 @@ || BX_PLATFORM_LINUX \ || BX_PLATFORM_WINDOWS \ || BX_PLATFORM_OSX \ + || BX_PLATFORM_NX \ ) +/// +#define BGFX_EMBEDDED_SHADER_CONCATENATE(_x, _y) BGFX_EMBEDDED_SHADER_CONCATENATE_(_x, _y) +#define BGFX_EMBEDDED_SHADER_CONCATENATE_(_x, _y) _x ## _y + +/// +#define BGFX_EMBEDDED_SHADER_COUNTOF(_x) (sizeof(_x)/sizeof(_x[0]) ) + #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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _dx11), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _pssl), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _essl), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _glsl), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _spv), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_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, BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _mtl), BGFX_EMBEDDED_SHADER_COUNTOF(BGFX_EMBEDDED_SHADER_CONCATENATE(_name, _mtl) ) }, #endif // BGFX_PLATFORM_SUPPORTS_METAL #define BGFX_EMBEDDED_SHADER(_name) \ diff --git a/libs/bgfx/src/bgfx.cpp b/libs/bgfx/src/bgfx.cpp index 5a8e51a..00e90c1 100644 --- a/libs/bgfx/src/bgfx.cpp +++ b/libs/bgfx/src/bgfx.cpp @@ -12,7 +12,7 @@ #include "topology.h" -#if BX_PLATFORM_OSX || BX_PLATFORM_IOS +#if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS # include #elif BX_PLATFORM_WINDOWS # ifndef WIN32_LEAN_AND_MEAN @@ -2413,7 +2413,7 @@ namespace bgfx } } -#if BX_PLATFORM_OSX || BX_PLATFORM_IOS +#if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS struct NSAutoreleasePoolScope { NSAutoreleasePoolScope() @@ -2437,7 +2437,7 @@ namespace bgfx { BGFX_PROFILER_SCOPE("bgfx::renderFrame", 0xff2040ff); -#if BX_PLATFORM_OSX || BX_PLATFORM_IOS +#if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS NSAutoreleasePoolScope pool; #endif // BX_PLATFORM_OSX @@ -2537,6 +2537,7 @@ namespace bgfx void Context::flushTextureUpdateBatch(CommandBuffer& _cmdbuf) { + BGFX_PROFILER_SCOPE("flushTextureUpdateBatch", 0xff2040ff); if (m_textureUpdateBatch.sort() ) { const uint32_t pos = _cmdbuf.m_pos; @@ -2635,11 +2636,11 @@ namespace bgfx { 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 { gnm::rendererCreate, gnm::rendererDestroy, BGFX_RENDERER_GNM_NAME, !!BGFX_CONFIG_RENDERER_GNM }, // GNM -#if BX_PLATFORM_OSX || BX_PLATFORM_IOS +#if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS { mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal #else { noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, false }, // Noop -#endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS +#endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS { nvn::rendererCreate, nvn::rendererDestroy, BGFX_RENDERER_NVN_NAME, !!BGFX_CONFIG_RENDERER_NVN }, // NVN { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL @@ -2737,7 +2738,7 @@ namespace bgfx score += RendererType::Metal == renderer ? 20 : 0; score += RendererType::Vulkan == renderer ? 10 : 0; } - else if (BX_ENABLED(BX_PLATFORM_IOS) ) + else if (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)) { score += RendererType::Metal == renderer ? 20 : 0; } diff --git a/libs/bgfx/src/bgfx_compute.sh b/libs/bgfx/src/bgfx_compute.sh index 9e8137f..d136004 100644 --- a/libs/bgfx/src/bgfx_compute.sh +++ b/libs/bgfx/src/bgfx_compute.sh @@ -32,22 +32,22 @@ #define readwrite #define IMAGE2D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readonly) #define UIMAGE2D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readonly) -#define IMAGE2D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, writeonly) -#define UIMAGE2D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, writeonly) +#define IMAGE2D_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, writeonly) +#define UIMAGE2D_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, writeonly) #define IMAGE2D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readwrite) #define UIMAGE2D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readwrite) #define IMAGE2D_ARRAY_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readonly) #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readonly) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, writeonly) -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, writeonly) +#define IMAGE2D_ARRAY_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, writeonly) +#define UIMAGE2D_ARRAY_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, writeonly) #define IMAGE2D_ARRAY_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readwrite) #define UIMAGE2D_ARRAY_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readwrite) #define IMAGE3D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readonly) #define UIMAGE3D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readonly) -#define IMAGE3D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, writeonly) -#define UIMAGE3D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, writeonly) +#define IMAGE3D_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, writeonly) +#define UIMAGE3D_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, writeonly) #define IMAGE3D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readwrite) #define UIMAGE3D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readwrite) @@ -59,7 +59,7 @@ #define BUFFER_RO(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readonly) #define BUFFER_RW(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readwrite) -#define BUFFER_WR(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, writeonly) +#define BUFFER_WO(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, writeonly) #define NUM_THREADS(_x, _y, _z) layout (local_size_x = _x, local_size_y = _y, local_size_z = _z) in; @@ -99,10 +99,10 @@ #define UIMAGE2D_RO(_name, _format, _reg) IMAGE2D_RO(_name, _format, _reg) -#define IMAGE2D_WR( _name, _format, _reg) \ +#define IMAGE2D_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ -#define UIMAGE2D_WR(_name, _format, _reg) IMAGE2D_WR(_name, _format, _reg) +#define UIMAGE2D_WO(_name, _format, _reg) IMAGE2D_WO(_name, _format, _reg) #define IMAGE2D_RW( _name, _format, _reg) \ FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ @@ -114,10 +114,10 @@ #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) IMAGE2D_ARRAY_RO(_name, _format, _reg) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) \ +#define IMAGE2D_ARRAY_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) IMAGE2D_ARRAY_WR(_name, _format, _reg) +#define UIMAGE2D_ARRAY_WO(_name, _format, _reg) IMAGE2D_ARRAY_WO(_name, _format, _reg) #define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ @@ -129,10 +129,10 @@ #define UIMAGE3D_RO(_name, _format, _reg) IMAGE3D_RO(_name, _format, _reg) -#define IMAGE3D_WR( _name, _format, _reg) \ +#define IMAGE3D_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); -#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) +#define UIMAGE3D_WO(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) #define IMAGE3D_RW( _name, _format, _reg) \ FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); \ @@ -142,11 +142,11 @@ #if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV #define BUFFER_RO(_name, _struct, _reg) StructuredBuffer<_struct> _name : REGISTER(t, _reg) #define BUFFER_RW(_name, _struct, _reg) RWStructuredBuffer <_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) +#define BUFFER_WO(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) #else #define BUFFER_RO(_name, _struct, _reg) Buffer<_struct> _name : REGISTER(t, _reg) #define BUFFER_RW(_name, _struct, _reg) RWBuffer<_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) +#define BUFFER_WO(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) #endif #define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)] diff --git a/libs/bgfx/src/bgfx_p.h b/libs/bgfx/src/bgfx_p.h index 7639daf..ec9e26c 100644 --- a/libs/bgfx/src/bgfx_p.h +++ b/libs/bgfx/src/bgfx_p.h @@ -1700,6 +1700,9 @@ namespace bgfx bind.m_idx = kInvalidHandle; bind.m_type = 0; bind.m_samplerFlags = 0; + bind.m_format = 0; + bind.m_access = 0; + bind.m_mip = 0; } } }; @@ -2168,6 +2171,8 @@ namespace bgfx bx::memSet(m_occlusion, 0xff, sizeof(m_occlusion) ); m_perfStats.viewStats = m_viewStats; + + bx::memSet(&m_renderItemBind[0], 0, sizeof(m_renderItemBind)); } ~Frame() @@ -2445,6 +2450,13 @@ namespace bgfx { EncoderImpl() { + // Although it will be cleared by the discard(), the fact that the + // struct is padded to have a size equal to the cache line size, + // will leaves bytes uninitialized. This will influence the hashing + // as it reads those bytes too. To make this deterministic, we will + // clear all bytes (inclusively the padding) before we start. + bx::memSet(&m_bind, 0, sizeof(m_bind)); + discard(BGFX_DISCARD_ALL); } @@ -2725,6 +2737,9 @@ namespace bgfx ? BGFX_SAMPLER_INTERNAL_DEFAULT : _flags ; + bind.m_format = 0; + bind.m_access = 0; + bind.m_mip = 0; if (isValid(_sampler) ) { diff --git a/libs/bgfx/src/config.h b/libs/bgfx/src/config.h index 6f4ec8c..f7b6a5c 100644 --- a/libs/bgfx/src/config.h +++ b/libs/bgfx/src/config.h @@ -63,6 +63,7 @@ # define BGFX_CONFIG_RENDERER_METAL (0 \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ + || BX_PLATFORM_VISIONOS \ ? 1 : 0) # endif // BGFX_CONFIG_RENDERER_METAL @@ -323,6 +324,22 @@ BX_STATIC_ASSERT(bx::isPowerOf2(BGFX_CONFIG_MAX_VIEWS), "BGFX_CONFIG_MAX_VIEWS m # define BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE (2<<20) #endif // BGFX_CONFIG_TRANSIENT_INDEX_BUFFER_SIZE +#ifndef BGFX_CONFIG_PER_FRAME_SCRATCH_STAGING_BUFFER_SIZE +/// Amount of scratch buffer size (per in-flight frame) that will be reserved +/// for staging data for copying to the device (such as vertex buffer data, +/// texture data, etc). This buffer will be used instead of allocating memory +/// on device separately for every data copy. +/// Note: Currently only used by the Vulkan backend. +# define BGFX_CONFIG_PER_FRAME_SCRATCH_STAGING_BUFFER_SIZE (32<<20) +#endif + +#ifndef BGFX_CONFIG_MAX_STAGING_SIZE_FOR_SCRACH_BUFFER +/// The threshold of data size above which the staging scratch buffer will +/// not be used, but instead a separate device memory allocation will take +/// place to stage the data for copying to device. +# define BGFX_CONFIG_MAX_STAGING_SIZE_FOR_SCRACH_BUFFER (16 << 20) +#endif + #ifndef BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT # define BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT 5 #endif // BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT diff --git a/libs/bgfx/src/dxgi.cpp b/libs/bgfx/src/dxgi.cpp index e3e6e6a..4eae796 100644 --- a/libs/bgfx/src/dxgi.cpp +++ b/libs/bgfx/src/dxgi.cpp @@ -278,7 +278,7 @@ namespace bgfx { AdapterI* adapter; for (uint32_t ii = 0 - ; DXGI_ERROR_NOT_FOUND != m_factory->EnumAdapters(ii, reinterpret_cast(&adapter) ) && ii < BX_COUNTOF(_caps.gpu) + ; ii < BX_COUNTOF(_caps.gpu) && DXGI_ERROR_NOT_FOUND != m_factory->EnumAdapters(ii, reinterpret_cast(&adapter) ) ; ++ii ) { diff --git a/libs/bgfx/src/glcontext_html5.cpp b/libs/bgfx/src/glcontext_html5.cpp index 430c870..6e89f48 100644 --- a/libs/bgfx/src/glcontext_html5.cpp +++ b/libs/bgfx/src/glcontext_html5.cpp @@ -71,7 +71,7 @@ namespace bgfx { namespace gl const char* canvas = (const char*) g_platformData.nwh; - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE) g_platformData.context; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = bx::narrowCast((uintptr_t) g_platformData.context); if (context > 0) { if (emscripten_webgl_get_context_attributes(context, &s_attrs) >= 0) diff --git a/libs/bgfx/src/renderer_gl.cpp b/libs/bgfx/src/renderer_gl.cpp index eefb253..c5b3648 100644 --- a/libs/bgfx/src/renderer_gl.cpp +++ b/libs/bgfx/src/renderer_gl.cpp @@ -6546,6 +6546,7 @@ namespace bgfx { namespace gl || usesVertexID || usesUint || usesTexelFetch + || usesGpuShader4 || usesGpuShader5 || usesInterpQ ? 130 diff --git a/libs/bgfx/src/renderer_mtl.h b/libs/bgfx/src/renderer_mtl.h index e22875a..26de5da 100644 --- a/libs/bgfx/src/renderer_mtl.h +++ b/libs/bgfx/src/renderer_mtl.h @@ -14,10 +14,14 @@ #import #import -#if BX_PLATFORM_IOS +#if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS # import #endif // BX_PLATFORM_* +#if BX_PLATFORM_VISIONOS +#import +#endif + #define BGFX_MTL_PROFILER_BEGIN(_view, _abgr) \ BX_MACRO_BLOCK_BEGIN \ BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \ @@ -38,7 +42,7 @@ namespace bgfx { namespace mtl //runtime os check inline bool iOSVersionEqualOrGreater(const char* _version) { -#if BX_PLATFORM_IOS +#if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); #else BX_UNUSED(_version); @@ -386,7 +390,7 @@ namespace bgfx { namespace mtl bool supportsTextureSampleCount(int sampleCount) { - if (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0") ) + if (BX_ENABLED(BX_PLATFORM_VISIONOS) || (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0")) ) return sampleCount == 1 || sampleCount == 2 || sampleCount == 4; else return [m_obj supportsTextureSampleCount:sampleCount]; @@ -394,11 +398,11 @@ namespace bgfx { namespace mtl bool depth24Stencil8PixelFormatSupported() { -#if BX_PLATFORM_IOS +#if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS return false; #else return m_obj.depth24Stencil8PixelFormatSupported; -#endif // BX_PLATFORM_IOS +#endif // BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS } MTL_CLASS_END @@ -1032,7 +1036,12 @@ namespace bgfx { namespace mtl struct SwapChainMtl { SwapChainMtl() +#if BX_PLATFORM_VISIONOS + : m_layerRenderer(NULL) + , m_frame(NULL) +#else : m_metalLayer(nil) +#endif , m_drawable(nil) , m_drawableTexture(nil) , m_backBufferColorMsaa() @@ -1049,8 +1058,15 @@ namespace bgfx { namespace mtl id currentDrawableTexture(); + +#if BX_PLATFORM_VISIONOS + cp_layer_renderer_t m_layerRenderer; + cp_frame_t m_frame; + cp_drawable_t m_drawable; +#else CAMetalLayer* m_metalLayer; - id m_drawable; + id m_drawable; +#endif id m_drawableTexture; Texture m_backBufferColorMsaa; Texture m_backBufferDepth; diff --git a/libs/bgfx/src/renderer_mtl.mm b/libs/bgfx/src/renderer_mtl.mm index cbaf0d0..e8cf00a 100644 --- a/libs/bgfx/src/renderer_mtl.mm +++ b/libs/bgfx/src/renderer_mtl.mm @@ -9,6 +9,7 @@ #include "renderer_mtl.h" #include "renderer.h" +#include #if BX_PLATFORM_OSX # include @@ -216,6 +217,8 @@ inline void setViewType(ViewId _view, const bx::StringView _str) bool m_autoGetMipmap; }; + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunguarded-availability-new"); static TextureFormatInfo s_textureFormat[] = { #define $0 MTLTextureSwizzleZero @@ -244,7 +247,7 @@ inline void setViewType(ViewId _view, const bx::StringView _str) { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATC { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCE { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCI -#if BX_PLATFORM_IOS && !TARGET_OS_MACCATALYST +#if (BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS) && !TARGET_OS_MACCATALYST { MTLPixelFormatASTC_4x4_LDR, MTLPixelFormatASTC_4x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC4x4 { MTLPixelFormatASTC_5x4_LDR, MTLPixelFormatASTC_5x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x4 { MTLPixelFormatASTC_5x5_LDR, MTLPixelFormatASTC_5x5_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x5 @@ -274,7 +277,7 @@ inline void setViewType(ViewId _view, const bx::StringView _str) { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC10x10 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x10 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x12 -#endif // BX_PLATFORM_IOS && !TARGET_OS_MACCATALYST +#endif // (BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS) && !TARGET_OS_MACCATALYST { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // Unknown { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // R1 { MTLPixelFormatA8Unorm, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // A8 @@ -344,6 +347,7 @@ inline void setViewType(ViewId _view, const bx::StringView _str) #undef $B #undef $A }; + BX_PRAGMA_DIAGNOSTIC_POP(); BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat) ); int32_t s_msaa[] = @@ -416,15 +420,56 @@ static uint32_t getEntryProperty(io_registry_entry_t _entry, CFStringRef _proper } #endif // BX_PLATFORM_OSX - static const char* s_accessNames[] = { "Access::Read", "Access::Write", "Access::ReadWrite", }; - BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNames count"); +#ifndef __IPHONE_OS_VERSION_MAX_ALLOWED +# define __IPHONE_OS_VERSION_MAX_ALLOWED 0 +#endif +#ifndef __MAC_OS_X_VERSION_MAX_ALLOWED +# define __MAC_OS_X_VERSION_MAX_ALLOWED 0 +#endif + +#ifndef BX_XCODE_15 +# define BX_XCODE_15 (0 \ + || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 140000) \ + || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 170000) \ + ) +#endif // BX_XCODE_15 + +#ifndef BX_XCODE_14 +# define BX_XCODE_14 (0 \ + || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 130000) \ + || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 160000) \ + ) +#endif // BX_XCODE_14 + +#ifndef BX_XCODE_13 +# define BX_XCODE_13 (0 \ + || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 120000) \ + || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 150000) \ + ) +#endif // BX_XCODE_13 + +#ifndef BX_XCODE_12 +# define BX_XCODE_12 (0 \ + || (__MAC_OS_X_VERSION_MAX_ALLOWED >= 110000) \ + || (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) \ + ) +#endif // BX_XCODE_12 + +#if BX_XCODE_15 +# define VISION_OS_MINIMUM visionOS 1.0, +# define VISION_OS_MINIMUM // TODO: [ZBGFX]: hack for compile +#else +# define VISION_OS_MINIMUM +# warning "XCode 15 is required for visionOS" +#endif + #define SHADER_FUNCTION_NAME "xlatMtlMain" #define SHADER_UNIFORM_NAME "_mtl_u" @@ -452,6 +497,14 @@ bool init(const Init& _init) BX_UNUSED(_init); BX_TRACE("Init."); +#define CHECK_FEATURE_AVAILABLE(feature, ...) if (@available(__VA_ARGS__)) { feature = true; } else { feature = false; } + + CHECK_FEATURE_AVAILABLE(m_usesMTLBindings, macOS 13.0, iOS 16.0, tvOS 16.0, macCatalyst 16.0, VISION_OS_MINIMUM *); + CHECK_FEATURE_AVAILABLE(m_hasCPUCacheModesAndStorageModes, iOS 9.0, macOS 10.11, macCatalyst 13.1, tvOS 9.0, VISION_OS_MINIMUM *); + CHECK_FEATURE_AVAILABLE(m_hasSynchronizeResource, macOS 10.11, macCatalyst 13.0, *); + CHECK_FEATURE_AVAILABLE(m_hasVSync, macOS 10.13, macCatalyst 13.1, *); + CHECK_FEATURE_AVAILABLE(m_hasMaximumDrawableCount, iOS 11.2, macOS 10.13.2, macCatalyst 13.1, tvOS 11.2, VISION_OS_MINIMUM *); + m_fbh.idx = kInvalidHandle; bx::memSet(m_uniforms, 0, sizeof(m_uniforms) ); bx::memSet(&m_resolution, 0, sizeof(m_resolution) ); @@ -481,7 +534,11 @@ bool init(const Init& _init) ); m_numWindows = 1; +#if BX_PLATFORM_VISIONOS + if (NULL == m_mainFrameBuffer.m_swapChain->m_layerRenderer) +#else if (NULL == m_mainFrameBuffer.m_swapChain->m_metalLayer) +#endif // BX_PLATFORM_VISIONOS { release(m_device); return false; @@ -545,7 +602,7 @@ bool init(const Init& _init) m_screenshotBlitProgram.create(&m_screenshotBlitProgramVsh, &m_screenshotBlitProgramFsh); reset(m_renderPipelineDescriptor); - m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; + m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain); m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); @@ -655,39 +712,39 @@ bool init(const Init& _init) // It is decremented by 1 because 1 entry is used for uniforms. g_caps.limits.maxComputeBindings = bx::uint32_min(30, BGFX_MAX_COMPUTE_BINDINGS); - m_hasPixelFormatDepth32Float_Stencil8 = false - || BX_ENABLED(BX_PLATFORM_OSX) - || (BX_ENABLED(BX_PLATFORM_IOS) && iOSVersionEqualOrGreater("9.0.0") ) - ; + CHECK_FEATURE_AVAILABLE(m_hasPixelFormatDepth32Float_Stencil8, iOS 9.0, macOS 10.11, macCatalyst 13.1, tvOS 9.0, VISION_OS_MINIMUM *); + CHECK_FEATURE_AVAILABLE(m_hasStoreActionStoreAndMultisampleResolve, iOS 10.0, macOS 10.12, macCatalyst 13.1, tvOS 10.0, VISION_OS_MINIMUM *); - m_hasStoreActionStoreAndMultisampleResolve = false - || (BX_ENABLED(BX_PLATFORM_OSX) && macOSVersionEqualOrGreater(10, 12, 0) ) - || (BX_ENABLED(BX_PLATFORM_IOS) && iOSVersionEqualOrGreater("10.0.0") ) - ; - - m_macOS11Runtime = true - && BX_ENABLED(BX_PLATFORM_OSX) - && macOSVersionEqualOrGreater(10, 11, 0) - ; - - m_iOS9Runtime = true - && BX_ENABLED(BX_PLATFORM_IOS) - && iOSVersionEqualOrGreater("9.0.0") - ; - - if (BX_ENABLED(BX_PLATFORM_OSX) ) + if (BX_ENABLED(BX_PLATFORM_OSX)) { s_textureFormat[TextureFormat::R8].m_fmtSrgb = MTLPixelFormatInvalid; s_textureFormat[TextureFormat::RG8].m_fmtSrgb = MTLPixelFormatInvalid; } + bool hasPacked16Formats; + CHECK_FEATURE_AVAILABLE(hasPacked16Formats, iOS 8.0, macOS 11.0, macCatalyst 14.0, tvOS 9.0, VISION_OS_MINIMUM *); + if (g_caps.vendorId == BGFX_PCI_ID_AMD) + { + hasPacked16Formats = false; + } + if (!hasPacked16Formats) + { + s_textureFormat[bgfx::TextureFormat::R5G6B5].m_fmt = MTLPixelFormatInvalid; + s_textureFormat[bgfx::TextureFormat::B5G6R5].m_fmt = MTLPixelFormatInvalid; + s_textureFormat[bgfx::TextureFormat::BGRA4].m_fmt = MTLPixelFormatInvalid; + s_textureFormat[bgfx::TextureFormat::RGBA4].m_fmt = MTLPixelFormatInvalid; + } + const MTLReadWriteTextureTier rwTier = [m_device readWriteTextureSupport]; g_caps.supported |= rwTier != MTLReadWriteTextureTierNone ? BGFX_CAPS_IMAGE_RW : 0 ; - if (!(iOSVersionEqualOrGreater("13.0.0") || macOSVersionEqualOrGreater(12, 0, 0))){ + bool hasD16Format; + CHECK_FEATURE_AVAILABLE(hasD16Format, iOS 13.0, macOS 10.12, macCatalyst 13.1, tvOS 13.0, VISION_OS_MINIMUM *); + if (!hasD16Format) + { s_textureFormat[TextureFormat::D16].m_fmt = MTLPixelFormatDepth32Float; } @@ -741,7 +798,7 @@ bool init(const Init& _init) g_caps.formats[TextureFormat::RGBA32I] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); g_caps.formats[TextureFormat::RGBA32U] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); - if (BX_ENABLED(BX_PLATFORM_IOS) ) + if (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)) { s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float_Stencil8; @@ -982,6 +1039,15 @@ void updateTextureEnd() override { } + MTLPixelFormat getSwapChainPixelFormat(SwapChainMtl *swapChain) + { +#if BX_PLATFORM_VISIONOS + return MTLPixelFormatBGRA8Unorm_sRGB; +#else + return swapChain->m_metalLayer.pixelFormat; +#endif // BX_PLATFORM_VISIONOS + } + void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override { const TextureMtl& texture = m_textures[_handle.idx]; @@ -1365,8 +1431,14 @@ void flip() override if (NULL != frameBuffer.m_swapChain->m_drawable) { +#if BX_PLATFORM_VISIONOS + cp_frame_start_submission(frameBuffer.m_swapChain->m_frame); + cp_drawable_encode_present(frameBuffer.m_swapChain->m_drawable, m_commandBuffer); + cp_frame_end_submission(frameBuffer.m_swapChain->m_frame); +#else m_commandBuffer.presentDrawable(frameBuffer.m_swapChain->m_drawable); MTL_RELEASE(frameBuffer.m_swapChain->m_drawable); +#endif // BX_PLATFORM_VISIONOS } } } @@ -1392,8 +1464,7 @@ void updateResolution(const Resolution& _resolution) || m_resolution.height != _resolution.height || (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) ) { - MTLPixelFormat prevMetalLayerPixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; - + MTLPixelFormat prevMetalLayerPixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain); m_resolution = _resolution; if (m_resolution.reset & BGFX_RESET_INTERNAL_FORCE @@ -1415,12 +1486,13 @@ void updateResolution(const Resolution& _resolution) m_textVideoMem.resize(false, _resolution.width, _resolution.height); m_textVideoMem.clear(); - if (prevMetalLayerPixelFormat != m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat) + + if (prevMetalLayerPixelFormat != getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain)) { MTL_RELEASE(m_screenshotBlitRenderPipelineState) reset(m_renderPipelineDescriptor); - m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; + m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain); m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); @@ -1933,6 +2005,9 @@ void setDepthStencilState(uint64_t _state, uint64_t _stencil = 0) m_renderCommandEncoder.setStencilReferenceValue(ref); } + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunguarded-availability-new"); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wincompatible-pointer-types"); void processArguments( PipelineStateMtl* ps , NSArray>* _vertexArgs @@ -1953,7 +2028,7 @@ void processArguments( { BX_TRACE("arg: %s type:%d", utf8String(arg.name), arg.type); - if (arg.used) + if ((!m_usesMTLBindings && [(MTLArgument*)arg isActive]) || (m_usesMTLBindings && arg.used)) { if (arg.type == MTLBindingTypeBuffer) { @@ -2101,6 +2176,7 @@ void processArguments( } } } + BX_PRAGMA_DIAGNOSTIC_POP(); PipelineStateMtl* getPipelineState( uint64_t _state @@ -2358,7 +2434,15 @@ void processArguments( if (NULL != reflection) { - processArguments(pso, reflection.vertexBindings, reflection.fragmentBindings); + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunguarded-availability-new"); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wincompatible-pointer-types"); + if (m_usesMTLBindings) { + processArguments(pso, reflection.vertexBindings, reflection.fragmentBindings); + } else { + processArguments(pso, reflection.vertexArguments, reflection.fragmentArguments); + } + BX_PRAGMA_DIAGNOSTIC_POP(); } } @@ -2405,7 +2489,16 @@ void processArguments( , MTLPipelineOptionBufferTypeInfo , &reflection ); - processArguments(pso, reflection.bindings, NULL); + + BX_PRAGMA_DIAGNOSTIC_PUSH(); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wunguarded-availability-new"); + BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG("-Wincompatible-pointer-types"); + if (m_usesMTLBindings) { + processArguments(pso, reflection.bindings, NULL); + } else { + processArguments(pso, reflection.arguments, NULL); + } + BX_PRAGMA_DIAGNOSTIC_POP(); for (uint32_t ii = 0; ii < 3; ++ii) { @@ -2502,10 +2595,13 @@ void endEncoding() TimerQueryMtl m_gpuTimer; CommandQueueMtl m_cmd; - bool m_iOS9Runtime; - bool m_macOS11Runtime; bool m_hasPixelFormatDepth32Float_Stencil8; bool m_hasStoreActionStoreAndMultisampleResolve; + bool m_hasCPUCacheModesAndStorageModes; + bool m_hasSynchronizeResource; + bool m_usesMTLBindings; + bool m_hasVSync; + bool m_hasMaximumDrawableCount; Buffer m_uniformBuffer; Buffer m_uniformBuffers[BGFX_CONFIG_MAX_FRAME_LATENCY]; @@ -2930,8 +3026,7 @@ void writeString(bx::WriterI* _writer, const char* _str) desc.arrayLength = ti.numLayers; desc.swizzle = tfi.m_mapping; - if (s_renderMtl->m_iOS9Runtime - || s_renderMtl->m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; @@ -2939,7 +3034,7 @@ void writeString(bx::WriterI* _writer, const char* _str) || writeOnly || bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) ? 2 /* MTLStorageModePrivate */ - : (BX_ENABLED(BX_PLATFORM_IOS) + : (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS) ? 0 /* MTLStorageModeShared */ : 1 /* MTLStorageModeManaged */ ) ); @@ -2963,8 +3058,7 @@ void writeString(bx::WriterI* _writer, const char* _str) desc.textureType = MTLTextureType2DMultisample; desc.sampleCount = sampleCount; - if (s_renderMtl->m_iOS9Runtime - || s_renderMtl->m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { desc.storageMode = (MTLStorageMode)(2 /* MTLStorageModePrivate */); } @@ -3130,11 +3224,10 @@ void writeString(bx::WriterI* _writer, const char* _str) desc.sampleCount = 1; desc.arrayLength = 1; - if (s_renderMtl->m_iOS9Runtime - || s_renderMtl->m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; - desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) + desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS) ? (MTLStorageMode)0 // MTLStorageModeShared : (MTLStorageMode)1 // MTLStorageModeManaged ; @@ -3222,8 +3315,13 @@ void writeString(bx::WriterI* _writer, const char* _str) SwapChainMtl::~SwapChainMtl() { +#if BX_PLATFORM_VISIONOS + MTL_RELEASE(m_layerRenderer); +#else MTL_RELEASE(m_metalLayer); MTL_RELEASE(m_drawable); +#endif // BX_PLATFORM_VISIONOS + MTL_RELEASE(m_drawableTexture); MTL_RELEASE(m_backBufferDepth); @@ -3238,14 +3336,24 @@ void writeString(bx::WriterI* _writer, const char* _str) void SwapChainMtl::init(void* _nwh) { +#if BX_PLATFORM_VISIONOS + { + cp_layer_renderer_t layerRenderer = (cp_layer_renderer_t)_nwh; + m_layerRenderer = layerRenderer; + retain(m_layerRenderer); + } +#else if (m_metalLayer) { release(m_metalLayer); } + if (NULL != NSClassFromString(@"MTKView") ) { MTKView *view = (MTKView *)_nwh; - if (NULL != view && [view isKindOfClass:NSClassFromString(@"MTKView")]) + + if (NULL != view + && [view isKindOfClass:NSClassFromString(@"MTKView")]) { m_metalLayer = (CAMetalLayer *)view.layer; } @@ -3254,7 +3362,7 @@ void writeString(bx::WriterI* _writer, const char* _str) if (NULL != NSClassFromString(@"CAMetalLayer") ) { if (NULL == m_metalLayer) -#if BX_PLATFORM_IOS +# if BX_PLATFORM_IOS { CAMetalLayer* metalLayer = (CAMetalLayer*)_nwh; if (NULL == metalLayer @@ -3266,7 +3374,7 @@ void writeString(bx::WriterI* _writer, const char* _str) m_metalLayer = metalLayer; } -#elif BX_PLATFORM_OSX +# elif BX_PLATFORM_OSX { NSObject* nvh = (NSObject*)_nwh; if ([nvh isKindOfClass:[CAMetalLayer class]]) @@ -3326,7 +3434,7 @@ void writeString(bx::WriterI* _writer, const char* _str) } } } -#endif // BX_PLATFORM_* +# endif // BX_PLATFORM_* } if (NULL == m_metalLayer) @@ -3338,8 +3446,10 @@ void writeString(bx::WriterI* _writer, const char* _str) m_metalLayer.device = s_renderMtl->m_device; m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; m_metalLayer.magnificationFilter = kCAFilterNearest; - m_nwh = _nwh; retain(m_metalLayer); +#endif // BX_PLATFORM_VISIONOS + + m_nwh = _nwh; } void SwapChainMtl::resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags, uint32_t _maximumDrawableCount) @@ -3348,12 +3458,12 @@ void writeString(bx::WriterI* _writer, const char* _str) #if BX_PLATFORM_OSX # if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 - if (@available(macOS 10.13, *) ) + if (s_renderMtl->m_hasVSync) { m_metalLayer.displaySyncEnabled = 0 != (_flags&BGFX_RESET_VSYNC); } - if (@available(macOS 10.13.2, *) ) + if (s_renderMtl->m_hasMaximumDrawableCount) { m_metalLayer.maximumDrawableCount = bx::clamp( _maximumDrawableCount != 0 ? _maximumDrawableCount : BGFX_CONFIG_MAX_FRAME_LATENCY @@ -3364,11 +3474,13 @@ void writeString(bx::WriterI* _writer, const char* _str) # endif // __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 #endif // BX_PLATFORM_OSX +#if !BX_PLATFORM_VISIONOS m_metalLayer.drawableSize = CGSizeMake(_width, _height); - m_metalLayer.pixelFormat = (_flags & BGFX_RESET_SRGB_BACKBUFFER) + m_metalLayer.pixelFormat = (_flags & BGFX_RESET_SRGB_BACKBUFFER) ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm ; +#endif // BX_PLATFORM_VISIONOS TextureDescriptor desc = s_renderMtl->m_textureDescriptor; @@ -3390,8 +3502,7 @@ void writeString(bx::WriterI* _writer, const char* _str) desc.sampleCount = sampleCount; desc.arrayLength = 1; - if (s_renderMtl->m_iOS9Runtime - || s_renderMtl->m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; desc.storageMode = MTLStorageModePrivate; @@ -3429,14 +3540,20 @@ void writeString(bx::WriterI* _writer, const char* _str) if (sampleCount > 1) { +#if BX_PLATFORM_VISIONOS + desc.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB; +#else desc.pixelFormat = m_metalLayer.pixelFormat; +#endif // BX_PLATFORM_VISIONOS m_backBufferColorMsaa = s_renderMtl->m_device.newTextureWithDescriptor(desc); } bx::HashMurmur2A murmur; murmur.begin(); murmur.add(1); +#if !BX_PLATFORM_VISIONOS murmur.add( (uint32_t)m_metalLayer.pixelFormat); +#endif // !BX_PLATFORM_VISIONOS murmur.add( (uint32_t)m_backBufferDepth.pixelFormat() ); murmur.add( (uint32_t)m_backBufferStencil.pixelFormat() ); murmur.add( (uint32_t)sampleCount); @@ -3447,30 +3564,49 @@ void writeString(bx::WriterI* _writer, const char* _str) { if (NULL == m_drawableTexture) { +#if BX_PLATFORM_VISIONOS + m_frame = cp_layer_renderer_query_next_frame(m_layerRenderer); + if (m_frame) + { + m_drawable = cp_frame_query_drawable(m_frame); + } +#else m_drawable = m_metalLayer.nextDrawable; +#endif // BX_PLATFORM_VISIONOS + if (m_drawable != NULL) { +#if BX_PLATFORM_VISIONOS + m_drawableTexture = cp_drawable_get_color_texture(m_drawable, 0); +#else m_drawableTexture = m_drawable.texture; - retain(m_drawableTexture); retain(m_drawable); // keep alive to be useable at 'flip' +#endif // BX_PLATFORM_VISIONOS + + retain(m_drawableTexture); } else { TextureDescriptor desc = s_renderMtl->m_textureDescriptor; desc.textureType = MTLTextureType2D; + +#if BX_PLATFORM_VISIONOS + desc.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB; +#else desc.pixelFormat = m_metalLayer.pixelFormat; desc.width = m_metalLayer.drawableSize.width; desc.height = m_metalLayer.drawableSize.height; +#endif // BX_PLATFORM_VISIONOS + desc.depth = 1; desc.mipmapLevelCount = 1; desc.sampleCount = 1; desc.arrayLength = 1; - if (s_renderMtl->m_iOS9Runtime - || s_renderMtl->m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; - desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) + desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS) ? (MTLStorageMode)0 // MTLStorageModeShared : (MTLStorageMode)1 // MTLStorageModeManaged ; @@ -3862,8 +3998,7 @@ static void setTimestamp(void* _data) , MTLOriginMake(blit.m_dstX, blit.m_dstY, blit.m_dstZ) ); #if BX_PLATFORM_OSX - if (m_macOS11Runtime - && readBack) + if (m_hasSynchronizeResource && readBack) { m_blitCommandEncoder.synchronizeResource(dst.m_ptr); } @@ -3883,8 +4018,7 @@ static void setTimestamp(void* _data) , MTLOriginMake(blit.m_dstX, blit.m_dstY, 0) ); #if BX_PLATFORM_OSX - if (m_macOS11Runtime - && readBack) + if (m_hasSynchronizeResource && readBack) { m_blitCommandEncoder.synchronizeTexture(dst.m_ptr, 0, blit.m_dstMip); } @@ -3938,7 +4072,7 @@ static void setTimestamp(void* _data) if (NULL == m_screenshotTarget) { m_textureDescriptor.textureType = MTLTextureType2D; - m_textureDescriptor.pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; + m_textureDescriptor.pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain); m_textureDescriptor.width = m_resolution.width; m_textureDescriptor.height = m_resolution.height; m_textureDescriptor.depth = 1; @@ -3946,11 +4080,10 @@ static void setTimestamp(void* _data) m_textureDescriptor.sampleCount = 1; m_textureDescriptor.arrayLength = 1; - if (m_iOS9Runtime - || m_macOS11Runtime) + if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) { m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; - m_textureDescriptor.storageMode = BX_ENABLED(BX_PLATFORM_IOS) + m_textureDescriptor.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS) ? (MTLStorageMode)0 // MTLStorageModeShared : (MTLStorageMode)1 // MTLStorageModeManaged ; diff --git a/libs/bgfx/src/renderer_noop.cpp b/libs/bgfx/src/renderer_noop.cpp index c3d746b..f926496 100644 --- a/libs/bgfx/src/renderer_noop.cpp +++ b/libs/bgfx/src/renderer_noop.cpp @@ -18,13 +18,17 @@ namespace bgfx { namespace noop | BGFX_CAPS_COMPUTE | BGFX_CAPS_CONSERVATIVE_RASTER | BGFX_CAPS_DRAW_INDIRECT + | BGFX_CAPS_DRAW_INDIRECT_COUNT | BGFX_CAPS_FRAGMENT_DEPTH | BGFX_CAPS_FRAGMENT_ORDERING | BGFX_CAPS_GRAPHICS_DEBUGGER + | BGFX_CAPS_HDR10 | BGFX_CAPS_HIDPI + | BGFX_CAPS_IMAGE_RW | BGFX_CAPS_INDEX32 | BGFX_CAPS_INSTANCING | BGFX_CAPS_OCCLUSION_QUERY + | BGFX_CAPS_PRIMITIVE_ID | BGFX_CAPS_RENDERER_MULTITHREADED | BGFX_CAPS_SWAP_CHAIN | BGFX_CAPS_TEXTURE_2D_ARRAY @@ -34,8 +38,11 @@ namespace bgfx { namespace noop | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL | BGFX_CAPS_TEXTURE_CUBE_ARRAY | BGFX_CAPS_TEXTURE_READ_BACK + | BGFX_CAPS_TRANSPARENT_BACKBUFFER | BGFX_CAPS_VERTEX_ATTRIB_HALF | BGFX_CAPS_VERTEX_ATTRIB_UINT10 + | BGFX_CAPS_VERTEX_ID + | BGFX_CAPS_VIEWPORT_LAYER_ARRAY ; // Pretend all features are available for all texture formats. diff --git a/libs/bgfx/src/renderer_vk.cpp b/libs/bgfx/src/renderer_vk.cpp index 4a9ba72..182f1c6 100644 --- a/libs/bgfx/src/renderer_vk.cpp +++ b/libs/bgfx/src/renderer_vk.cpp @@ -1325,8 +1325,15 @@ VK_IMPORT if (BX_ENABLED(BGFX_CONFIG_DEBUG) ) { - s_allocationCb.pUserData = g_allocator; - m_allocatorCb = &s_allocationCb; + // Validation layer is calling freeFunction with pointers that are not allocated + // via callback mechanism. This is bug in validation layer, and work-around + // would be to keep track of allocated pointers and ignore those that are not + // allocated by it. + // + // Anyhow we just let VK take care of memory, until they fix the issue... + // + // s_allocationCb.pUserData = g_allocator; + // m_allocatorCb = &s_allocationCb; BX_UNUSED(s_allocationCb); } @@ -1914,9 +1921,9 @@ VK_IMPORT_DEVICE m_textVideoMem.resize(false, _init.resolution.width, _init.resolution.height); m_textVideoMem.clear(); - for (uint8_t ii = 0; ii < BX_COUNTOF(m_swapchainFormats); ++ii) + for (uint8_t ii = 0; ii < BX_COUNTOF(m_swapChainFormats); ++ii) { - m_swapchainFormats[ii] = TextureFormat::Enum(ii); + m_swapChainFormats[ii] = TextureFormat::Enum(ii); } result = m_backBuffer.create(UINT16_MAX, g_platformData.nwh, m_resolution.width, m_resolution.height, m_resolution.format); @@ -1980,10 +1987,17 @@ VK_IMPORT_DEVICE { const uint32_t size = 128; const uint32_t count = BGFX_CONFIG_MAX_DRAW_CALLS; + for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii) { BX_TRACE("Create scratch buffer %d", ii); - m_scratchBuffer[ii].create(size, count); + m_scratchBuffer[ii].createUniform(size, count); + } + + for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii) + { + BX_TRACE("Create scratch staging buffer %d", ii); + m_scratchStagingBuffer[ii].createStaging(BGFX_CONFIG_PER_FRAME_SCRATCH_STAGING_BUFFER_SIZE); } } @@ -2051,6 +2065,7 @@ VK_IMPORT_DEVICE for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii) { m_scratchBuffer[ii].destroy(); + m_scratchStagingBuffer[ii].destroy(); } vkDestroy(m_pipelineCache); vkDestroy(m_descriptorPool); @@ -2115,6 +2130,11 @@ VK_IMPORT_DEVICE m_scratchBuffer[ii].destroy(); } + for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii) + { + m_scratchStagingBuffer[ii].destroy(); + } + for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii) { m_frameBuffers[ii].destroy(); @@ -2763,12 +2783,14 @@ VK_IMPORT_DEVICE | BGFX_RESET_DEPTH_CLAMP ); - // Note: m_needToRefreshSwapchain is deliberately ignored when deciding whether to recreate the swapchain - // because it can happen several frames before submit is called with the new resolution. - // Instead, vkAcquireNextImageKHR and all draws to the backbuffer are skipped until the window size is updated. - // That also fixes a related issue where VK_ERROR_OUT_OF_DATE_KHR is returned from - // vkQueuePresentKHR when the window doesn't exist anymore, and vkGetPhysicalDeviceSurfaceCapabilitiesKHR - // fails with VK_ERROR_SURFACE_LOST_KHR. + // Note: m_needToRefreshSwapchain is deliberately ignored when deciding whether to + // recreate the swapchain because it can happen several frames before submit is called + // with the new resolution. + // + // Instead, vkAcquireNextImageKHR and all draws to the backbuffer are skipped until + // the window size is updated. That also fixes a related issue where VK_ERROR_OUT_OF_DATE_KHR + // is returned from vkQueuePresentKHR when the window doesn't exist anymore, and + // vkGetPhysicalDeviceSurfaceCapabilitiesKHR fails with VK_ERROR_SURFACE_LOST_KHR. if (false || m_resolution.format != _resolution.format @@ -2824,6 +2846,7 @@ VK_IMPORT_DEVICE void setFrameBuffer(FrameBufferHandle _fbh, bool _acquire = true) { + BGFX_PROFILER_SCOPE("Vk::setFrameBuffer()", kColorFrame); BX_ASSERT(false || isValid(_fbh) || NULL != m_backBuffer.m_nwh @@ -4273,6 +4296,10 @@ VK_IMPORT_DEVICE if (0 != depthAspectMask) { + attachments[mrt].colorAttachment = VK_ATTACHMENT_UNUSED; + // The above is meaningless and not required by the spec, but Khronos + // Validation Layer has a conditional jump depending on this, even + // without VK_IMAGE_ASPECT_COLOR_BIT set. Valgrind found this. attachments[mrt].aspectMask = depthAspectMask; attachments[mrt].clearValue.depthStencil.stencil = _clear.m_stencil; attachments[mrt].clearValue.depthStencil.depth = _clear.m_depth; @@ -4310,6 +4337,7 @@ VK_IMPORT_DEVICE VkResult allocateMemory(const VkMemoryRequirements* requirements, VkMemoryPropertyFlags propertyFlags, ::VkDeviceMemory* memory) const { + BGFX_PROFILER_SCOPE("RendererContextVK::allocateMemory", kColorResource); VkMemoryAllocateInfo ma; ma.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; ma.pNext = NULL; @@ -4336,6 +4364,7 @@ VK_IMPORT_DEVICE VkResult createHostBuffer(uint32_t _size, VkMemoryPropertyFlags _flags, ::VkBuffer* _buffer, ::VkDeviceMemory* _memory, const void* _data = NULL) { + BGFX_PROFILER_SCOPE("createHostBuffer", kColorResource); VkResult result = VK_SUCCESS; VkBufferCreateInfo bci; @@ -4381,6 +4410,7 @@ VK_IMPORT_DEVICE if (_data != NULL) { + BGFX_PROFILER_SCOPE("map and copy data", kColorResource); void* dst; result = vkMapMemory(m_device, *_memory, 0, _size, 0, &dst); if (VK_SUCCESS != result) @@ -4405,6 +4435,48 @@ VK_IMPORT_DEVICE return createHostBuffer(_size, flags, _buffer, _memory, _data); } + StagingBufferVK allocFromScratchStagingBuffer(uint32_t _size, uint32_t _align, const void *_data = NULL) + { + BGFX_PROFILER_SCOPE("allocFromScratchStagingBuffer", kColorResource); + + StagingBufferVK result; + ScratchBufferVK &scratch = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight]; + + if (_size <= BGFX_CONFIG_MAX_STAGING_SIZE_FOR_SCRACH_BUFFER) + { + const uint32_t scratchOffset = scratch.alloc(_size, _align); + + if (scratchOffset != UINT32_MAX) + { + result.m_isFromScratch = true; + result.m_size = _size; + result.m_offset = scratchOffset; + result.m_buffer = scratch.m_buffer; + result.m_deviceMem = scratch.m_deviceMem; + result.m_data = scratch.m_data + result.m_offset; + + if (_data != NULL) + { + BGFX_PROFILER_SCOPE("copy to scratch", kColorResource); + bx::memCopy(result.m_data, _data, _size); + } + + return result; + } + } + + // Not enough space or too big, we will create a new staging buffer on the spot. + result.m_isFromScratch = false; + + VK_CHECK(createStagingBuffer(_size, &result.m_buffer, &result.m_deviceMem, _data)); + + result.m_size = _size; + result.m_offset = 0; + result.m_data = NULL; + + return result; + } + VkResult createReadbackBuffer(uint32_t _size, ::VkBuffer* _buffer, ::VkDeviceMemory* _memory) { const VkMemoryPropertyFlags flags = 0 @@ -4412,6 +4484,7 @@ VK_IMPORT_DEVICE | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT ; + return createHostBuffer(_size, flags, _buffer, _memory, NULL); } @@ -4430,13 +4503,14 @@ VK_IMPORT_DEVICE bool m_timerQuerySupport; FrameBufferVK m_backBuffer; - TextureFormat::Enum m_swapchainFormats[TextureFormat::Count]; + TextureFormat::Enum m_swapChainFormats[TextureFormat::Count]; uint16_t m_numWindows; FrameBufferHandle m_windows[BGFX_CONFIG_MAX_FRAME_BUFFERS]; int64_t m_presentElapsed; ScratchBufferVK m_scratchBuffer[BGFX_CONFIG_MAX_FRAME_LATENCY]; + ScratchBufferVK m_scratchStagingBuffer[BGFX_CONFIG_MAX_FRAME_LATENCY]; uint32_t m_numFramesInFlight; CommandQueueVK m_cmd; @@ -4515,6 +4589,7 @@ VK_IMPORT_DEVICE { \ if (VK_NULL_HANDLE != _obj) \ { \ + BGFX_PROFILER_SCOPE("vkDestroy" #_name, kColorResource); \ vkDestroy##_name(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb); \ _obj = VK_NULL_HANDLE; \ } \ @@ -4530,6 +4605,7 @@ VK_DESTROY { if (VK_NULL_HANDLE != _obj) { + BGFX_PROFILER_SCOPE("vkFreeMemory", kColorResource); vkFreeMemory(s_renderVK->m_device, _obj.vk, s_renderVK->m_allocatorCb); _obj = VK_NULL_HANDLE; } @@ -4539,6 +4615,7 @@ VK_DESTROY { if (VK_NULL_HANDLE != _obj) { + BGFX_PROFILER_SCOPE("vkDestroySurfaceKHR", kColorResource); vkDestroySurfaceKHR(s_renderVK->m_instance, _obj.vk, s_renderVK->m_allocatorCb); _obj = VK_NULL_HANDLE; } @@ -4548,6 +4625,7 @@ VK_DESTROY { if (VK_NULL_HANDLE != _obj) { + BGFX_PROFILER_SCOPE("vkFreeDescriptorSets", kColorResource); vkFreeDescriptorSets(s_renderVK->m_device, s_renderVK->m_descriptorPool, 1, &_obj); _obj = VK_NULL_HANDLE; } @@ -4568,14 +4646,12 @@ VK_DESTROY s_renderVK->release(_obj); } - void ScratchBufferVK::create(uint32_t _size, uint32_t _count) + void ScratchBufferVK::create(uint32_t _size, uint32_t _count, VkBufferUsageFlags usage, uint32_t _align) { const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; const VkDevice device = s_renderVK->m_device; - const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits; - const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment); - const uint32_t entrySize = bx::strideAlign(_size, align); + const uint32_t entrySize = bx::strideAlign(_size, _align); const uint32_t totalSize = entrySize * _count; VkBufferCreateInfo bci; @@ -4583,7 +4659,7 @@ VK_DESTROY bci.pNext = NULL; bci.flags = 0; bci.size = totalSize; - bci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bci.usage = usage; bci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; bci.queueFamilyIndexCount = 0; bci.pQueueFamilyIndices = NULL; @@ -4613,12 +4689,29 @@ VK_DESTROY m_size = (uint32_t)mr.size; m_pos = 0; + m_align = _align; VK_CHECK(vkBindBufferMemory(device, m_buffer, m_deviceMem, 0) ); VK_CHECK(vkMapMemory(device, m_deviceMem, 0, m_size, 0, (void**)&m_data) ); } + void ScratchBufferVK::createUniform(uint32_t _size, uint32_t _count) + { + const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits; + const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment); + + create(_size, _count, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, align); + } + + void ScratchBufferVK::createStaging(uint32_t _size) + { + const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits; + const uint32_t align = uint32_t(deviceLimits.optimalBufferCopyOffsetAlignment); + + create(_size, 1, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, align); + } + void ScratchBufferVK::destroy() { reset(); @@ -4634,26 +4727,34 @@ VK_DESTROY m_pos = 0; } - uint32_t ScratchBufferVK::write(const void* _data, uint32_t _size) + uint32_t ScratchBufferVK::alloc(uint32_t _size, uint32_t _minAlign) { - BX_ASSERT(m_pos < m_size, "Out of scratch buffer memory"); - - const uint32_t offset = m_pos; + const uint32_t align = bx::uint32_lcm(m_align, _minAlign); + const uint32_t dstOffset = bx::strideAlign(m_pos, align); - if (_size > 0) + if (dstOffset + _size <= m_size) { - bx::memCopy(&m_data[m_pos], _data, _size); + m_pos = dstOffset + _size; + return dstOffset; + } + + return UINT32_MAX; + } - const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits; - const uint32_t align = uint32_t(deviceLimits.minUniformBufferOffsetAlignment); - const uint32_t alignedSize = bx::strideAlign(_size, align); + uint32_t ScratchBufferVK::write(const void* _data, uint32_t _size, uint32_t _minAlign) + { + uint32_t dstOffset = alloc(_size, _minAlign); + BX_ASSERT(dstOffset != UINT32_MAX, "Not enough space on ScratchBuffer left to allocate %u bytes with alignment %u.", _size, _minAlign); - m_pos += alignedSize; + if (_size > 0) + { + bx::memCopy(&m_data[dstOffset], _data, _size); } - return offset; + return dstOffset; } + void ScratchBufferVK::flush() { const VkPhysicalDeviceLimits& deviceLimits = s_renderVK->m_deviceProperties.limits; @@ -4716,17 +4817,16 @@ VK_DESTROY void BufferVK::update(VkCommandBuffer _commandBuffer, uint32_t _offset, uint32_t _size, void* _data, bool _discard) { + BGFX_PROFILER_SCOPE("BufferVK::update", kColorFrame); BX_UNUSED(_discard); - VkBuffer stagingBuffer; - VkDeviceMemory stagingMem; - VK_CHECK(s_renderVK->createStagingBuffer(_size, &stagingBuffer, &stagingMem, _data) ); + StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(_size, 8, _data); VkBufferCopy region; - region.srcOffset = 0; + region.srcOffset = stagingBuffer.m_offset; region.dstOffset = _offset; region.size = _size; - vkCmdCopyBuffer(_commandBuffer, stagingBuffer, m_buffer, 1, ®ion); + vkCmdCopyBuffer(_commandBuffer, stagingBuffer.m_buffer, m_buffer, 1, ®ion); setMemoryBarrier( _commandBuffer @@ -4734,8 +4834,11 @@ VK_DESTROY , VK_PIPELINE_STAGE_TRANSFER_BIT ); - s_renderVK->release(stagingBuffer); - s_renderVK->release(stagingMem); + if (!stagingBuffer.m_isFromScratch) + { + s_renderVK->release(stagingBuffer.m_buffer); + s_renderVK->release(stagingBuffer.m_deviceMem); + } } void BufferVK::destroy() @@ -5298,6 +5401,7 @@ VK_DESTROY VkResult TimerQueryVK::init() { + BGFX_PROFILER_SCOPE("TimerQueryVK::init", kColorFrame); VkResult result = VK_SUCCESS; const VkDevice device = s_renderVK->m_device; @@ -5361,6 +5465,7 @@ VK_DESTROY uint32_t TimerQueryVK::begin(uint32_t _resultIdx, uint32_t _frameNum) { + BGFX_PROFILER_SCOPE("TimerQueryVK::begin", kColorFrame); while (0 == m_control.reserve(1) ) { m_control.consume(1); @@ -5388,6 +5493,7 @@ VK_DESTROY void TimerQueryVK::end(uint32_t _idx) { + BGFX_PROFILER_SCOPE("TimerQueryVK::end", kColorFrame); Query& query = m_query[_idx]; query.m_ready = true; query.m_completed = s_renderVK->m_cmd.m_submitted + s_renderVK->m_cmd.m_numFramesInFlight; @@ -5450,6 +5556,7 @@ VK_DESTROY VkResult OcclusionQueryVK::init() { + BGFX_PROFILER_SCOPE("OcclusionQueryVK::init", kColorFrame); VkResult result = VK_SUCCESS; const VkDevice device = s_renderVK->m_device; @@ -5506,6 +5613,7 @@ VK_DESTROY void OcclusionQueryVK::begin(OcclusionQueryHandle _handle) { + BGFX_PROFILER_SCOPE("OcclusionQueryVK::shutdown", kColorFrame); m_control.reserve(1); const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer; @@ -5516,6 +5624,7 @@ VK_DESTROY void OcclusionQueryVK::end() { + BGFX_PROFILER_SCOPE("OcclusionQueryVK::end", kColorFrame); const VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer; const OcclusionQueryHandle handle = m_handle[m_control.m_current]; @@ -5526,6 +5635,7 @@ VK_DESTROY void OcclusionQueryVK::flush(Frame* _render) { + BGFX_PROFILER_SCOPE("OcclusionQueryVK::flush", kColorFrame); if (0 < m_control.available() ) { VkCommandBuffer commandBuffer = s_renderVK->m_commandBuffer; @@ -5614,6 +5724,7 @@ VK_DESTROY void ReadbackVK::copyImageToBuffer(VkCommandBuffer _commandBuffer, VkBuffer _buffer, VkImageLayout _layout, VkImageAspectFlags _aspect, uint8_t _mip) const { + BGFX_PROFILER_SCOPE("ReadbackVK::copyImageToBuffer", kColorFrame); uint32_t mipWidth = bx::uint32_max(1, m_width >> _mip); uint32_t mipHeight = bx::uint32_max(1, m_height >> _mip); @@ -5671,6 +5782,7 @@ VK_DESTROY void ReadbackVK::readback(VkDeviceMemory _memory, VkDeviceSize _offset, void* _data, uint8_t _mip) const { + BGFX_PROFILER_SCOPE("ReadbackVK::readback", kColorResource); if (m_image == VK_NULL_HANDLE) { return; @@ -5696,6 +5808,7 @@ VK_DESTROY VkResult TextureVK::create(VkCommandBuffer _commandBuffer, uint32_t _width, uint32_t _height, uint64_t _flags, VkFormat _format) { + BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource); BX_ASSERT(0 != (_flags & BGFX_TEXTURE_RT_MASK), ""); _flags |= BGFX_TEXTURE_RT_WRITE_ONLY; @@ -5730,6 +5843,7 @@ VK_DESTROY VkResult TextureVK::createImages(VkCommandBuffer _commandBuffer) { + BGFX_PROFILER_SCOPE("TextureVK::createImages", kColorResource); VkResult result = VK_SUCCESS; const VkAllocationCallbacks* allocatorCb = s_renderVK->m_allocatorCb; @@ -5859,6 +5973,7 @@ VK_DESTROY void* TextureVK::create(VkCommandBuffer _commandBuffer, const Memory* _mem, uint64_t _flags, uint8_t _skip) { + BGFX_PROFILER_SCOPE("TextureVK::create", kColorResource); bimg::ImageContainer imageContainer; if (bimg::imageParse(imageContainer, _mem->data, _mem->size) ) @@ -6085,34 +6200,53 @@ VK_DESTROY if (totalMemSize > 0) { const VkDevice device = s_renderVK->m_device; + const bimg::ImageBlockInfo &dstBlockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat)); - VkBuffer stagingBuffer; - VkDeviceMemory stagingDeviceMem; - VK_CHECK(s_renderVK->createStagingBuffer(totalMemSize, &stagingBuffer, &stagingDeviceMem) ); + StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(totalMemSize, dstBlockInfo.blockSize); uint8_t* mappedMemory; - VK_CHECK(vkMapMemory( - device - , stagingDeviceMem - , 0 - , totalMemSize - , 0 - , (void**)&mappedMemory - ) ); + + if (!stagingBuffer.m_isFromScratch) + { + VK_CHECK(vkMapMemory( + device + , stagingBuffer.m_deviceMem + , 0 + , totalMemSize + , 0 + , (void**)&mappedMemory + ) ); + } + else + { + mappedMemory = stagingBuffer.m_data; + } // copy image to staging buffer for (uint32_t ii = 0; ii < numSrd; ++ii) { bx::memCopy(mappedMemory, imageInfos[ii].data, imageInfos[ii].size); mappedMemory += imageInfos[ii].size; + bufferCopyInfo[ii].bufferOffset += stagingBuffer.m_offset; + BX_ASSERT( + bx::uint32_mod(bufferCopyInfo[ii].bufferOffset, dstBlockInfo.blockSize) == 0 + , "Alignment for subimage %u is not aligned correctly (%u)." + , ii, bufferCopyInfo[ii].bufferOffset, dstBlockInfo.blockSize + ); } - vkUnmapMemory(device, stagingDeviceMem); + if (!stagingBuffer.m_isFromScratch) + { + vkUnmapMemory(device, stagingBuffer.m_deviceMem); + } - copyBufferToTexture(_commandBuffer, stagingBuffer, numSrd, bufferCopyInfo); + copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, numSrd, bufferCopyInfo); - s_renderVK->release(stagingBuffer); - s_renderVK->release(stagingDeviceMem); + if (!stagingBuffer.m_isFromScratch) + { + s_renderVK->release(stagingBuffer.m_buffer); + s_renderVK->release(stagingBuffer.m_deviceMem); + } } else { @@ -6136,6 +6270,7 @@ VK_DESTROY void TextureVK::destroy() { + BGFX_PROFILER_SCOPE("TextureVK::destroy", kColorResource); m_readback.destroy(); if (VK_NULL_HANDLE != m_textureImage) @@ -6156,12 +6291,14 @@ VK_DESTROY void TextureVK::update(VkCommandBuffer _commandBuffer, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { + BGFX_PROFILER_SCOPE("TextureVK::update", kColorResource); const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) ); uint32_t rectpitch = _rect.m_width * bpp / 8; uint32_t slicepitch = rectpitch * _rect.m_height; + uint32_t align = blockInfo.blockSize; if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat) ) ) { - const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat) ); rectpitch = (_rect.m_width / blockInfo.blockWidth ) * blockInfo.blockSize; slicepitch = (_rect.m_height / blockInfo.blockHeight) * rectpitch; } @@ -6197,9 +6334,11 @@ VK_DESTROY }; } - VkBuffer stagingBuffer = VK_NULL_HANDLE; - VkDeviceMemory stagingDeviceMem = VK_NULL_HANDLE; - VK_CHECK(s_renderVK->createStagingBuffer(size, &stagingBuffer, &stagingDeviceMem, data) ); + StagingBufferVK stagingBuffer = s_renderVK->allocFromScratchStagingBuffer(size, align, data); + region.bufferOffset += stagingBuffer.m_offset; + BX_ASSERT(region.bufferOffset % align == 0, + "Alignment for image (mip %u, z %s) is not aligned correctly (%u).", + _mip, _z, region.bufferOffset, align); if (VK_IMAGE_VIEW_TYPE_3D == m_type) { @@ -6215,10 +6354,13 @@ VK_DESTROY region.imageSubresource.baseArrayLayer = _z; } - copyBufferToTexture(_commandBuffer, stagingBuffer, 1, ®ion); + copyBufferToTexture(_commandBuffer, stagingBuffer.m_buffer, 1, ®ion); - s_renderVK->release(stagingBuffer); - s_renderVK->release(stagingDeviceMem); + if (!stagingBuffer.m_isFromScratch) + { + s_renderVK->release(stagingBuffer.m_buffer); + s_renderVK->release(stagingBuffer.m_deviceMem); + } if (NULL != temp) { @@ -6228,6 +6370,7 @@ VK_DESTROY void TextureVK::resolve(VkCommandBuffer _commandBuffer, uint8_t _resolve, uint32_t _layer, uint32_t _numLayers, uint32_t _mip) { + BGFX_PROFILER_SCOPE("TextureVK::resolve", kColorResource); const bool needResolve = VK_NULL_HANDLE != m_singleMsaaImage; const bool needMipGen = true @@ -6235,11 +6378,19 @@ VK_DESTROY && 0 != (m_flags & BGFX_TEXTURE_RT_MASK) && 0 == (m_flags & BGFX_TEXTURE_RT_WRITE_ONLY) && (_mip + 1) < m_numMips - && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS); + && 0 != (_resolve & BGFX_RESOLVE_AUTO_GEN_MIPS) + ; const VkImageLayout oldLayout = m_currentImageLayout; const VkImageLayout oldSingleMsaaLayout = m_currentSingleMsaaImageLayout; + const uint32_t numLayers = false + || m_type == VK_IMAGE_VIEW_TYPE_CUBE + || m_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + ? m_numSides + : _numLayers + ; + if (needResolve) { setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); @@ -6255,11 +6406,11 @@ VK_DESTROY resolve.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; resolve.srcSubresource.mipLevel = _mip; resolve.srcSubresource.baseArrayLayer = _layer; - resolve.srcSubresource.layerCount = _numLayers; + resolve.srcSubresource.layerCount = numLayers; resolve.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; resolve.dstSubresource.mipLevel = _mip; resolve.dstSubresource.baseArrayLayer = _layer; - resolve.dstSubresource.layerCount = _numLayers; + resolve.dstSubresource.layerCount = numLayers; resolve.extent.width = m_width; resolve.extent.height = m_height; resolve.extent.depth = 1; @@ -6277,6 +6428,7 @@ VK_DESTROY if (needMipGen) { + BGFX_PROFILER_SCOPE("TextureVK::resolve genMipmaps", kColorResource); setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); int32_t mipWidth = bx::max(int32_t(m_width) >> _mip, 1); @@ -6290,19 +6442,20 @@ VK_DESTROY VkImageBlit blit; blit.srcOffsets[0] = { 0, 0, 0 }; blit.srcOffsets[1] = { mipWidth, mipHeight, 1 }; - blit.srcSubresource.aspectMask = m_aspectMask; - blit.srcSubresource.mipLevel = 0; + blit.srcSubresource.aspectMask = m_aspectMask; + blit.srcSubresource.mipLevel = 0; blit.srcSubresource.baseArrayLayer = _layer; - blit.srcSubresource.layerCount = _numLayers; + blit.srcSubresource.layerCount = numLayers; blit.dstOffsets[0] = { 0, 0, 0 }; blit.dstOffsets[1] = { mipWidth, mipHeight, 1 }; - blit.dstSubresource.aspectMask = m_aspectMask; - blit.dstSubresource.mipLevel = 0; + blit.dstSubresource.aspectMask = m_aspectMask; + blit.dstSubresource.mipLevel = 0; blit.dstSubresource.baseArrayLayer = _layer; - blit.dstSubresource.layerCount = _numLayers; + blit.dstSubresource.layerCount = numLayers; for (uint32_t i = _mip + 1; i < m_numMips; i++) { + BGFX_PROFILER_SCOPE("mipmap", kColorResource); blit.srcOffsets[1] = { mipWidth, mipHeight, 1 }; blit.srcSubresource.mipLevel = i - 1; @@ -6321,7 +6474,7 @@ VK_DESTROY , blit.srcSubresource.mipLevel , 1 , _layer - , _numLayers + , numLayers ); vkCmdBlitImage( @@ -6345,7 +6498,7 @@ VK_DESTROY , _mip , m_numMips - _mip - 1 , _layer - , _numLayers + , numLayers ); } @@ -6355,6 +6508,7 @@ VK_DESTROY void TextureVK::copyBufferToTexture(VkCommandBuffer _commandBuffer, VkBuffer _stagingBuffer, uint32_t _bufferImageCopyCount, VkBufferImageCopy* _bufferImageCopy) { + BGFX_PROFILER_SCOPE("TextureVK::copyBufferToTexture", kColorResource); const VkImageLayout oldLayout = m_currentImageLayout == VK_IMAGE_LAYOUT_UNDEFINED ? m_sampledLayout : m_currentImageLayout @@ -6362,6 +6516,16 @@ VK_DESTROY setImageMemoryBarrier(_commandBuffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + bimg::TextureFormat::Enum tf = bimg::TextureFormat::Enum(m_textureFormat); + const bimg::ImageBlockInfo &blockInfo = bimg::getBlockInfo(tf); + for (uint32_t i = 0; i < _bufferImageCopyCount; ++i) { + BX_ASSERT( + bx::uint32_mod(_bufferImageCopy[i].bufferOffset, blockInfo.blockSize) == 0 + , "Misaligned texture of type %s to offset %u, which is not a multiple of %u." + , bimg::getName(tf), _bufferImageCopy[i].bufferOffset, blockInfo.blockSize + ); + } + vkCmdCopyBufferToImage( _commandBuffer , _stagingBuffer @@ -6545,7 +6709,11 @@ VK_DESTROY m_sci.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; m_sci.queueFamilyIndexCount = 0; m_sci.pQueueFamilyIndices = NULL; + #ifdef BX_PLATFORM_NX + m_sci.preTransform = VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR; + #else m_sci.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + #endif m_sci.oldSwapchain = VK_NULL_HANDLE; for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) @@ -6624,7 +6792,7 @@ VK_DESTROY void SwapChainVK::destroy() { - if (VK_NULL_HANDLE != m_swapchain) + if (VK_NULL_HANDLE != m_swapChain) { releaseFrameBuffer(); releaseAttachments(); @@ -6641,6 +6809,7 @@ VK_DESTROY void SwapChainVK::update(VkCommandBuffer _commandBuffer, void* _nwh, const Resolution& _resolution) { + BGFX_PROFILER_SCOPE("SwapChainVK::update", kColorFrame); const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice; m_lastImageRenderedSemaphore = VK_NULL_HANDLE; @@ -6730,6 +6899,7 @@ VK_DESTROY VkResult SwapChainVK::createSurface() { + BGFX_PROFILER_SCOPE("SwapChainVK::createSurface", kColorFrame); VkResult result = VK_ERROR_INITIALIZATION_FAILED; const VkInstance instance = s_renderVK->m_instance; @@ -6887,6 +7057,7 @@ VK_DESTROY VkResult SwapChainVK::createSwapChain() { + BGFX_PROFILER_SCOPE("SwapChainVK::createSwapchain", kColorFrame); VkResult result = VK_SUCCESS; const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice; @@ -6991,41 +7162,47 @@ VK_DESTROY m_sci.presentMode = s_presentMode[presentModeIdx].mode; m_sci.clipped = VK_FALSE; - result = vkCreateSwapchainKHR(device, &m_sci, allocatorCb, &m_swapchain); + result = vkCreateSwapchainKHR(device, &m_sci, allocatorCb, &m_swapChain); if (VK_SUCCESS != result) { BX_TRACE("Create swapchain error: vkCreateSwapchainKHR failed %d: %s.", result, getName(result) ); return result; } - m_sci.oldSwapchain = m_swapchain; + m_sci.oldSwapchain = m_swapChain; - result = vkGetSwapchainImagesKHR(device, m_swapchain, &m_numSwapchainImages, NULL); + result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, NULL); if (VK_SUCCESS != result) { BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s.", result, getName(result) ); return result; } - if (m_numSwapchainImages < m_sci.minImageCount) + BX_TRACE("Create swapchain numSwapChainImages %d, minImageCount %d, BX_COUNTOF(m_backBufferColorImage) %d" + , m_numSwapChainImages + , m_sci.minImageCount + , BX_COUNTOF(m_backBufferColorImage) + ); + + if (m_numSwapChainImages < m_sci.minImageCount) { BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d < minImageCount %d." - , m_numSwapchainImages + , m_numSwapChainImages , m_sci.minImageCount ); return VK_ERROR_INITIALIZATION_FAILED; } - if (m_numSwapchainImages > BX_COUNTOF(m_backBufferColorImage) ) + if (m_numSwapChainImages > BX_COUNTOF(m_backBufferColorImage) ) { BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR: numSwapchainImages %d > countof(m_backBufferColorImage) %d." - , m_numSwapchainImages + , m_numSwapChainImages , BX_COUNTOF(m_backBufferColorImage) ); return VK_ERROR_INITIALIZATION_FAILED; } - result = vkGetSwapchainImagesKHR(device, m_swapchain, &m_numSwapchainImages, &m_backBufferColorImage[0]); + result = vkGetSwapchainImagesKHR(device, m_swapChain, &m_numSwapChainImages, &m_backBufferColorImage[0]); if (VK_SUCCESS != result && VK_INCOMPLETE != result) { BX_TRACE("Create swapchain error: vkGetSwapchainImagesKHR failed %d: %s." @@ -7051,7 +7228,7 @@ VK_DESTROY ivci.subresourceRange.baseArrayLayer = 0; ivci.subresourceRange.layerCount = 1; - for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) + for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii) { ivci.image = m_backBufferColorImage[ii]; @@ -7071,7 +7248,10 @@ VK_DESTROY sci.pNext = NULL; sci.flags = 0; - for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) + // We will make a fully filled pool of semaphores and cycle through those. + // This is to make sure we have enough, even in the case where there are + // more frames in flight than images on the swapchain. + for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii) { if (VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_presentDoneSemaphore[ii]) || VK_SUCCESS != vkCreateSemaphore(device, &sci, allocatorCb, &m_renderDoneSemaphore[ii]) ) @@ -7092,21 +7272,26 @@ VK_DESTROY void SwapChainVK::releaseSwapChain() { + BGFX_PROFILER_SCOPE("SwapChainVK::releaseSwapChain", kColorFrame); for (uint32_t ii = 0; ii < BX_COUNTOF(m_backBufferColorImageView); ++ii) { release(m_backBufferColorImageView[ii]); m_backBufferFence[ii] = VK_NULL_HANDLE; + } + for (uint32_t ii = 0; ii < kMaxBackBuffers; ++ii) + { release(m_presentDoneSemaphore[ii]); release(m_renderDoneSemaphore[ii]); } - release(m_swapchain); + release(m_swapChain); } VkResult SwapChainVK::createAttachments(VkCommandBuffer _commandBuffer) { + BGFX_PROFILER_SCOPE("SwapChainVK::createAttachments", kColorFrame); VkResult result = VK_SUCCESS; const uint32_t samplerIndex = (m_resolution.reset & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT; @@ -7182,6 +7367,7 @@ VK_DESTROY void SwapChainVK::releaseAttachments() { + BGFX_PROFILER_SCOPE("SwapChainVK::releaseAttachments", kColorFrame); release(m_backBufferDepthStencilImageView); release(m_backBufferColorMsaaImageView); @@ -7191,6 +7377,7 @@ VK_DESTROY VkResult SwapChainVK::createFrameBuffer() { + BGFX_PROFILER_SCOPE("SwapChainVK::createFrameBuffer", kColorFrame); VkResult result = VK_SUCCESS; const VkDevice device = s_renderVK->m_device; @@ -7204,7 +7391,7 @@ VK_DESTROY return result; } - for (uint32_t ii = 0; ii < m_numSwapchainImages; ++ii) + for (uint32_t ii = 0; ii < m_numSwapChainImages; ++ii) { uint32_t numAttachments = 2; ::VkImageView attachments[3] = @@ -7252,6 +7439,7 @@ VK_DESTROY uint32_t SwapChainVK::findPresentMode(bool _vsync) { + BGFX_PROFILER_SCOPE("SwapChainVK::findPresentMode", kColorFrame); VkResult result = VK_SUCCESS; const VkPhysicalDevice physicalDevice = s_renderVK->m_physicalDevice; @@ -7313,6 +7501,7 @@ VK_DESTROY TextureFormat::Enum SwapChainVK::findSurfaceFormat(TextureFormat::Enum _format, VkColorSpaceKHR _colorSpace, bool _srgb) { + BGFX_PROFILER_SCOPE("SwapChainVK::findSurfaceFormat", kColorFrame); VkResult result = VK_SUCCESS; TextureFormat::Enum selectedFormat = TextureFormat::Count; @@ -7360,9 +7549,9 @@ VK_DESTROY { selectedFormat = requested; if (0 != ii - && s_renderVK->m_swapchainFormats[_format] != selectedFormat) + && s_renderVK->m_swapChainFormats[_format] != selectedFormat) { - s_renderVK->m_swapchainFormats[_format] = selectedFormat; + s_renderVK->m_swapChainFormats[_format] = selectedFormat; BX_TRACE( "findSurfaceFormat: Surface format %s not found! Defaulting to %s." , bimg::getName(bimg::TextureFormat::Enum(_format) ) @@ -7386,7 +7575,8 @@ VK_DESTROY bool SwapChainVK::acquire(VkCommandBuffer _commandBuffer) { - if (VK_NULL_HANDLE == m_swapchain + BGFX_PROFILER_SCOPE("SwapChainVK::acquire", kColorFrame); + if (VK_NULL_HANDLE == m_swapChain || m_needToRefreshSwapchain) { return false; @@ -7398,16 +7588,20 @@ VK_DESTROY m_lastImageAcquiredSemaphore = m_presentDoneSemaphore[m_currentSemaphore]; m_lastImageRenderedSemaphore = m_renderDoneSemaphore[m_currentSemaphore]; - m_currentSemaphore = (m_currentSemaphore + 1) % m_numSwapchainImages; - - VkResult result = vkAcquireNextImageKHR( - device - , m_swapchain - , UINT64_MAX - , m_lastImageAcquiredSemaphore - , VK_NULL_HANDLE - , &m_backBufferColorIdx - ); + m_currentSemaphore = (m_currentSemaphore + 1) % kMaxBackBuffers; + + VkResult result; + { + BGFX_PROFILER_SCOPE("vkAcquireNextImageKHR", kColorFrame); + result = vkAcquireNextImageKHR( + device + , m_swapChain + , UINT64_MAX + , m_lastImageAcquiredSemaphore + , VK_NULL_HANDLE + , &m_backBufferColorIdx + ); + } switch (result) { @@ -7430,6 +7624,7 @@ VK_DESTROY if (VK_NULL_HANDLE != m_backBufferFence[m_backBufferColorIdx]) { + BGFX_PROFILER_SCOPE("vkWaitForFences", kColorFrame); VK_CHECK(vkWaitForFences( device , 1 @@ -7449,7 +7644,8 @@ VK_DESTROY void SwapChainVK::present() { - if (VK_NULL_HANDLE != m_swapchain + BGFX_PROFILER_SCOPE("SwapChainVk::present", kColorFrame); + if (VK_NULL_HANDLE != m_swapChain && m_needPresent) { VkPresentInfoKHR pi; @@ -7458,10 +7654,14 @@ VK_DESTROY pi.waitSemaphoreCount = 1; pi.pWaitSemaphores = &m_lastImageRenderedSemaphore; pi.swapchainCount = 1; - pi.pSwapchains = &m_swapchain; + pi.pSwapchains = &m_swapChain; pi.pImageIndices = &m_backBufferColorIdx; pi.pResults = NULL; - VkResult result = vkQueuePresentKHR(m_queue, &pi); + VkResult result; + { + BGFX_PROFILER_SCOPE("vkQueuePresentHKR", kColorFrame); + result = vkQueuePresentKHR(m_queue, &pi); + } switch (result) { @@ -7510,6 +7710,7 @@ VK_DESTROY void FrameBufferVK::create(uint8_t _num, const Attachment* _attachment) { + BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame); m_numTh = _num; bx::memCopy(m_attachment, _attachment, sizeof(Attachment) * _num); @@ -7518,6 +7719,7 @@ VK_DESTROY VkResult FrameBufferVK::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) { + BGFX_PROFILER_SCOPE("FrameBufferVK::create", kColorFrame); VkResult result = VK_SUCCESS; Resolution resolution = s_renderVK->m_resolution; @@ -7554,6 +7756,7 @@ VK_DESTROY void FrameBufferVK::preReset() { + BGFX_PROFILER_SCOPE("FrameBufferVK::preReset", kColorFrame); if (VK_NULL_HANDLE != m_framebuffer) { s_renderVK->release(m_framebuffer); @@ -7567,6 +7770,7 @@ VK_DESTROY void FrameBufferVK::postReset() { + BGFX_PROFILER_SCOPE("FrameBufferVK::postReset", kColorFrame); if (m_numTh > 0) { const VkDevice device = s_renderVK->m_device; @@ -7627,6 +7831,7 @@ VK_DESTROY void FrameBufferVK::update(VkCommandBuffer _commandBuffer, const Resolution& _resolution) { + BGFX_PROFILER_SCOPE("FrameBufferVK::update", kColorResource); m_swapChain.update(_commandBuffer, m_nwh, _resolution); VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &m_renderPass) ); m_width = _resolution.width; @@ -7641,6 +7846,7 @@ VK_DESTROY return; } + BGFX_PROFILER_SCOPE("FrameBufferVK::resolve", kColorFrame); if (NULL == m_nwh) { for (uint32_t ii = 0; ii < m_numTh; ++ii) @@ -7672,6 +7878,7 @@ VK_DESTROY uint16_t FrameBufferVK::destroy() { + BGFX_PROFILER_SCOPE("FrameBufferVK::destroy", kColorFrame); preReset(); if (NULL != m_nwh) @@ -7694,6 +7901,7 @@ VK_DESTROY bool FrameBufferVK::acquire(VkCommandBuffer _commandBuffer) { + BGFX_PROFILER_SCOPE("FrameBufferVK::acquire", kColorFrame); bool acquired = true; if (NULL != m_nwh) @@ -7710,6 +7918,7 @@ VK_DESTROY void FrameBufferVK::present() { + BGFX_PROFILER_SCOPE("FrameBufferVK::present", kColorFrame); m_swapChain.present(); m_needPresent = false; } @@ -7728,6 +7937,7 @@ VK_DESTROY m_queue = _queue; m_numFramesInFlight = bx::clamp(_numFramesInFlight, 1, BGFX_CONFIG_MAX_FRAME_LATENCY); m_activeCommandBuffer = VK_NULL_HANDLE; + m_consumeIndex = 0; return reset(); } @@ -7828,6 +8038,7 @@ VK_DESTROY VkResult CommandQueueVK::alloc(VkCommandBuffer* _commandBuffer) { + BGFX_PROFILER_SCOPE("CommandQueueVK::alloc", kColorResource); VkResult result = VK_SUCCESS; if (m_activeCommandBuffer == VK_NULL_HANDLE) @@ -7835,7 +8046,10 @@ VK_DESTROY const VkDevice device = s_renderVK->m_device; CommandList& commandList = m_commandList[m_currentFrameInFlight]; - result = vkWaitForFences(device, 1, &commandList.m_fence, VK_TRUE, UINT64_MAX); + { + BGFX_PROFILER_SCOPE("vkWaitForFences", kColorFrame); + result = vkWaitForFences(device, 1, &commandList.m_fence, VK_TRUE, UINT64_MAX); + } if (VK_SUCCESS != result) { @@ -7896,6 +8110,7 @@ VK_DESTROY void CommandQueueVK::kick(bool _wait) { + BGFX_PROFILER_SCOPE("CommandQueueVK::kick", kColorDraw); if (VK_NULL_HANDLE != m_activeCommandBuffer) { const VkDevice device = s_renderVK->m_device; @@ -7927,10 +8142,14 @@ VK_DESTROY m_numWaitSemaphores = 0; m_numSignalSemaphores = 0; - VK_CHECK(vkQueueSubmit(m_queue, 1, &si, m_completedFence) ); + { + BGFX_PROFILER_SCOPE("CommandQueueVK::kick vkQueueSubmit", kColorDraw); + VK_CHECK(vkQueueSubmit(m_queue, 1, &si, m_completedFence) ); + } if (_wait) { + BGFX_PROFILER_SCOPE("CommandQueue::kick vkWaitForFences", kColorDraw); VK_CHECK(vkWaitForFences(device, 1, &m_completedFence, VK_TRUE, UINT64_MAX) ); } @@ -7943,6 +8162,7 @@ VK_DESTROY void CommandQueueVK::finish(bool _finishAll) { + BGFX_PROFILER_SCOPE("CommandQueueVK::finish", kColorDraw); if (_finishAll) { for (uint32_t ii = 0; ii < m_numFramesInFlight; ++ii) @@ -7968,6 +8188,7 @@ VK_DESTROY void CommandQueueVK::consume() { + BGFX_PROFILER_SCOPE("CommandQueueVK::consume", kColorResource); m_consumeIndex = (m_consumeIndex + 1) % m_numFramesInFlight; for (const Resource& resource : m_release[m_consumeIndex]) @@ -7999,6 +8220,7 @@ VK_DESTROY void RendererContextVK::submitBlit(BlitState& _bs, uint16_t _view) { + BGFX_PROFILER_SCOPE("RendererContextVK::submitBlit", kColorFrame); VkImageLayout srcLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS]; VkImageLayout dstLayouts[BGFX_CONFIG_MAX_BLIT_ITEMS]; @@ -8206,6 +8428,9 @@ VK_DESTROY ScratchBufferVK& scratchBuffer = m_scratchBuffer[m_cmd.m_currentFrameInFlight]; scratchBuffer.reset(); + ScratchBufferVK& scratchStagingBuffer = m_scratchStagingBuffer[m_cmd.m_currentFrameInFlight]; + scratchStagingBuffer.reset(); + setMemoryBarrier( m_commandBuffer , VK_PIPELINE_STAGE_TRANSFER_BIT @@ -9068,7 +9293,7 @@ VK_DESTROY } pos = 10; - tvm.printf(10, pos++, 0x8b, " Frame: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS " + tvm.printf(10, pos++, 0x8b, " Frame: % 7.3f, % 7.3f \x1f, % 7.3f \x1e [ms] / % 6.2f FPS" , double(frameTime)*toMs , double(min)*toMs , double(max)*toMs @@ -9089,11 +9314,14 @@ VK_DESTROY ); double elapsedCpuMs = double(frameTime)*toMs; - tvm.printf(10, pos++, 0x8b, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] " + tvm.printf(10, pos++, 0x8b, " Submitted: %5d (draw %5d, compute %4d) / CPU %7.4f [ms] %c GPU %7.4f [ms] (latency %d) " , _render->m_numRenderItems , statsKeyType[0] , statsKeyType[1] , elapsedCpuMs + , elapsedCpuMs > maxGpuElapsed ? '>' : '<' + , maxGpuElapsed + , maxGpuLatency ); for (uint32_t ii = 0; ii < Topology::Count; ++ii) @@ -9159,7 +9387,15 @@ VK_DESTROY m_presentElapsed = 0; - scratchBuffer.flush(); + { + BGFX_PROFILER_SCOPE("scratchBuffer::flush", kColorResource); + scratchBuffer.flush(); + } + + { + BGFX_PROFILER_SCOPE("scratchStagingBuffer::flush", kColorResource); + scratchStagingBuffer.flush(); + } for (uint16_t ii = 0; ii < m_numWindows; ++ii) { diff --git a/libs/bgfx/src/renderer_vk.h b/libs/bgfx/src/renderer_vk.h index a9f6be8..b138ba9 100644 --- a/libs/bgfx/src/renderer_vk.h +++ b/libs/bgfx/src/renderer_vk.h @@ -389,6 +389,17 @@ VK_DESTROY_FUNC(DescriptorSet); HashMap m_hashMap; }; + struct StagingBufferVK + { + VkBuffer m_buffer; + VkDeviceMemory m_deviceMem; + + uint8_t* m_data; + uint32_t m_size; + uint32_t m_offset; + bool m_isFromScratch; + }; + class ScratchBufferVK { public: @@ -400,17 +411,22 @@ VK_DESTROY_FUNC(DescriptorSet); { } - void create(uint32_t _size, uint32_t _count); + void create(uint32_t _size, uint32_t _count, VkBufferUsageFlags _usage, uint32_t align); + void createUniform(uint32_t _size, uint32_t _count); + void createStaging(uint32_t _size); void destroy(); void reset(); - uint32_t write(const void* _data, uint32_t _size); + uint32_t alloc(uint32_t _size, uint32_t _minAlign = 1); + uint32_t write(const void* _data, uint32_t _size, uint32_t _minAlign = 1); void flush(); VkBuffer m_buffer; VkDeviceMemory m_deviceMem; + uint8_t* m_data; uint32_t m_size; uint32_t m_pos; + uint32_t m_align; }; struct BufferVK @@ -705,7 +721,7 @@ VK_DESTROY_FUNC(DescriptorSet); { SwapChainVK() : m_nwh(NULL) - , m_swapchain(VK_NULL_HANDLE) + , m_swapChain(VK_NULL_HANDLE) , m_lastImageRenderedSemaphore(VK_NULL_HANDLE) , m_lastImageAcquiredSemaphore(VK_NULL_HANDLE) , m_backBufferColorMsaaImageView(VK_NULL_HANDLE) @@ -746,8 +762,8 @@ VK_DESTROY_FUNC(DescriptorSet); TextureFormat::Enum m_depthFormat; VkSurfaceKHR m_surface; - VkSwapchainKHR m_swapchain; - uint32_t m_numSwapchainImages; + VkSwapchainKHR m_swapChain; + uint32_t m_numSwapChainImages; VkImageLayout m_backBufferColorImageLayout[kMaxBackBuffers]; VkImage m_backBufferColorImage[kMaxBackBuffers]; VkImageView m_backBufferColorImageView[kMaxBackBuffers]; diff --git a/libs/bgfx/src/shader_spirv.cpp b/libs/bgfx/src/shader_spirv.cpp index dc4f122..185fdfd 100644 --- a/libs/bgfx/src/shader_spirv.cpp +++ b/libs/bgfx/src/shader_spirv.cpp @@ -17,12 +17,8 @@ namespace bgfx #define SPV_OPERAND_7(_a0, _a1, _a2, _a3, _a4, _a5, _a6) SPV_OPERAND_1(_a0), SPV_OPERAND_6(_a1, _a2, _a3, _a4, _a5, _a6) #define SPV_OPERAND_8(_a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7) SPV_OPERAND_1(_a0), SPV_OPERAND_7(_a1, _a2, _a3, _a4, _a5, _a6, _a7) #define SPV_OPERAND_9(_a0, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) SPV_OPERAND_1(_a0), SPV_OPERAND_8(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) -#if BX_COMPILER_MSVC -// Workaround MSVS bug... -# define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__) BX_VA_ARGS_PASS(__VA_ARGS__) } -#else -# define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__)(__VA_ARGS__) } -#endif // BX_COMPILER_MSVC +#define SPV_OPERAND(...) { BX_MACRO_DISPATCHER(SPV_OPERAND_, __VA_ARGS__)(__VA_ARGS__) } + #define _ Count bool isDebug(SpvOpcode::Enum _opcode) diff --git a/libs/bgfx/src/version.h b/libs/bgfx/src/version.h index 1caa1df..d387534 100644 --- a/libs/bgfx/src/version.h +++ b/libs/bgfx/src/version.h @@ -9,5 +9,5 @@ * */ -#define BGFX_REV_NUMBER 8709 -#define BGFX_REV_SHA1 "2ad67a4dfd721c266d2286ce5ad19a64e1373531" +#define BGFX_REV_NUMBER 8775 +#define BGFX_REV_SHA1 "a476c5b9a42d3779af59a0099d4d222fa8898d36" diff --git a/libs/bgfx/tools/shaderc/shaderc.cpp b/libs/bgfx/tools/shaderc/shaderc.cpp index 8bfd6ab..7f90bdc 100644 --- a/libs/bgfx/tools/shaderc/shaderc.cpp +++ b/libs/bgfx/tools/shaderc/shaderc.cpp @@ -40,20 +40,19 @@ namespace bgfx }; }; - static const char* s_shadingLangName[] = - { - "OpenGL ES Shading Language / WebGL (ESSL)", - "OpenGL Shading Language (GLSL)", - "High-Level Shading Language (HLSL)", - "Metal Shading Language (MSL)", - "PlayStation Shader Language (PSSL)", - "Standard Portable Intermediate Representation - V (SPIR-V)", - - "Unknown?!" - }; - BX_STATIC_ASSERT(BX_COUNTOF(s_shadingLangName) == ShadingLang::Count+1, "ShadingLang::Enum and s_shadingLangName mismatch"); + static const char *s_shadingLangName[] = + { + "OpenGL ES Shading Language / WebGL (ESSL)", + "OpenGL Shading Language (GLSL)", + "High-Level Shading Language (HLSL)", + "Metal Shading Language (MSL)", + "PlayStation Shader Language (PSSL)", + "Standard Portable Intermediate Representation - V (SPIR-V)", - const char* getName(ShadingLang::Enum _lang) + "Unknown?!"}; + BX_STATIC_ASSERT(BX_COUNTOF(s_shadingLangName) == ShadingLang::Count + 1, "ShadingLang::Enum and s_shadingLangName mismatch"); + + const char *getName(ShadingLang::Enum _lang) { return s_shadingLangName[_lang]; } @@ -114,232 +113,225 @@ namespace bgfx }; static const Profile s_profiles[] = - { - { ShadingLang::ESSL, 100, "100_es" }, - { ShadingLang::ESSL, 300, "300_es" }, - { ShadingLang::ESSL, 310, "310_es" }, - { ShadingLang::ESSL, 320, "320_es" }, - { ShadingLang::HLSL, 400, "s_4_0" }, - { ShadingLang::HLSL, 500, "s_5_0" }, - { ShadingLang::Metal, 1210, "metal" }, - { ShadingLang::Metal, 1000, "metal10-10" }, - { ShadingLang::Metal, 1110, "metal11-10" }, - { ShadingLang::Metal, 1210, "metal12-10" }, - { ShadingLang::Metal, 2011, "metal20-11" }, - { ShadingLang::Metal, 2111, "metal21-11" }, - { ShadingLang::Metal, 2211, "metal22-11" }, - { ShadingLang::Metal, 2314, "metal23-14" }, - { ShadingLang::Metal, 2414, "metal24-14" }, - { ShadingLang::Metal, 3014, "metal30-14" }, - { ShadingLang::Metal, 3114, "metal31-14" }, - { ShadingLang::PSSL, 1000, "pssl" }, - { ShadingLang::SpirV, 1010, "spirv" }, - { ShadingLang::SpirV, 1010, "spirv10-10" }, - { ShadingLang::SpirV, 1311, "spirv13-11" }, - { ShadingLang::SpirV, 1411, "spirv14-11" }, - { ShadingLang::SpirV, 1512, "spirv15-12" }, - { ShadingLang::SpirV, 1613, "spirv16-13" }, - { ShadingLang::GLSL, 120, "120" }, - { ShadingLang::GLSL, 130, "130" }, - { ShadingLang::GLSL, 140, "140" }, - { ShadingLang::GLSL, 150, "150" }, - { ShadingLang::GLSL, 330, "330" }, - { ShadingLang::GLSL, 400, "400" }, - { ShadingLang::GLSL, 410, "410" }, - { ShadingLang::GLSL, 420, "420" }, - { ShadingLang::GLSL, 430, "430" }, - { ShadingLang::GLSL, 440, "440" }, + { + {ShadingLang::ESSL, 100, "100_es"}, + {ShadingLang::ESSL, 300, "300_es"}, + {ShadingLang::ESSL, 310, "310_es"}, + {ShadingLang::ESSL, 320, "320_es"}, + {ShadingLang::HLSL, 400, "s_4_0"}, + {ShadingLang::HLSL, 500, "s_5_0"}, + {ShadingLang::Metal, 1210, "metal"}, + {ShadingLang::Metal, 1000, "metal10-10"}, + {ShadingLang::Metal, 1110, "metal11-10"}, + {ShadingLang::Metal, 1210, "metal12-10"}, + {ShadingLang::Metal, 2011, "metal20-11"}, + {ShadingLang::Metal, 2111, "metal21-11"}, + {ShadingLang::Metal, 2211, "metal22-11"}, + {ShadingLang::Metal, 2314, "metal23-14"}, + {ShadingLang::Metal, 2414, "metal24-14"}, + {ShadingLang::Metal, 3014, "metal30-14"}, + {ShadingLang::Metal, 3114, "metal31-14"}, + {ShadingLang::PSSL, 1000, "pssl"}, + {ShadingLang::SpirV, 1010, "spirv"}, + {ShadingLang::SpirV, 1010, "spirv10-10"}, + {ShadingLang::SpirV, 1311, "spirv13-11"}, + {ShadingLang::SpirV, 1411, "spirv14-11"}, + {ShadingLang::SpirV, 1512, "spirv15-12"}, + {ShadingLang::SpirV, 1613, "spirv16-13"}, + {ShadingLang::GLSL, 120, "120"}, + {ShadingLang::GLSL, 130, "130"}, + {ShadingLang::GLSL, 140, "140"}, + {ShadingLang::GLSL, 150, "150"}, + {ShadingLang::GLSL, 330, "330"}, + {ShadingLang::GLSL, 400, "400"}, + {ShadingLang::GLSL, 410, "410"}, + {ShadingLang::GLSL, 420, "420"}, + {ShadingLang::GLSL, 430, "430"}, + {ShadingLang::GLSL, 440, "440"}, }; - static const char* s_ARB_shader_texture_lod[] = - { - "texture2DLod", - "texture2DArrayLod", // BK - interacts with ARB_texture_array. - "texture2DProjLod", - "texture2DGrad", - "texture2DProjGrad", - "texture3DLod", - "texture3DProjLod", - "texture3DGrad", - "texture3DProjGrad", - "textureCubeLod", - "textureCubeGrad", - "shadow2DLod", - "shadow2DProjLod", - NULL - // "texture1DLod", - // "texture1DProjLod", - // "shadow1DLod", - // "shadow1DProjLod", + static const char *s_ARB_shader_texture_lod[] = + { + "texture2DLod", + "texture2DArrayLod", // BK - interacts with ARB_texture_array. + "texture2DProjLod", + "texture2DGrad", + "texture2DProjGrad", + "texture3DLod", + "texture3DProjLod", + "texture3DGrad", + "texture3DProjGrad", + "textureCubeLod", + "textureCubeGrad", + "shadow2DLod", + "shadow2DProjLod", + NULL + // "texture1DLod", + // "texture1DProjLod", + // "shadow1DLod", + // "shadow1DProjLod", }; - static const char* s_EXT_shader_texture_lod[] = - { - "texture2DLod", - "texture2DProjLod", - "textureCubeLod", - "texture2DGrad", - "texture2DProjGrad", - "textureCubeGrad", - NULL - }; + static const char *s_EXT_shader_texture_lod[] = + { + "texture2DLod", + "texture2DProjLod", + "textureCubeLod", + "texture2DGrad", + "texture2DProjGrad", + "textureCubeGrad", + NULL}; - static const char* s_EXT_shadow_samplers[] = - { - "shadow2D", - "shadow2DProj", - "sampler2DShadow", - NULL - }; + static const char *s_EXT_shadow_samplers[] = + { + "shadow2D", + "shadow2DProj", + "sampler2DShadow", + NULL}; - static const char* s_OES_standard_derivatives[] = - { - "dFdx", - "dFdy", - "fwidth", - NULL - }; + static const char *s_OES_standard_derivatives[] = + { + "dFdx", + "dFdy", + "fwidth", + NULL}; - static const char* s_OES_texture_3D[] = - { - "texture3D", - "texture3DProj", - "texture3DLod", - "texture3DProjLod", - NULL - }; + static const char *s_OES_texture_3D[] = + { + "texture3D", + "texture3DProj", + "texture3DLod", + "texture3DProjLod", + NULL}; - static const char* s_EXT_gpu_shader4[] = - { - "gl_VertexID", - "gl_InstanceID", - "texture2DLodOffset", - NULL - }; + static const char *s_EXT_gpu_shader4[] = + { + "gl_VertexID", + "gl_InstanceID", + "texture2DLodOffset", + NULL}; // To be use from vertex program require: // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shader_viewport_layer_array.txt // DX11 11_1 feature level - static const char* s_ARB_shader_viewport_layer_array[] = - { - "gl_ViewportIndex", - "gl_Layer", - NULL - }; - - static const char* s_ARB_gpu_shader5[] = - { - "bitfieldReverse", - "floatBitsToInt", - "floatBitsToUint", - "intBitsToFloat", - "uintBitsToFloat", - NULL - }; - - static const char* s_ARB_shading_language_packing[] = - { - "packHalf2x16", - "unpackHalf2x16", - NULL - }; - - static const char* s_130[] = - { - "uint", - "uint2", - "uint3", - "uint4", - "isampler2D", - "usampler2D", - "isampler3D", - "usampler3D", - "isamplerCube", - "usamplerCube", - "textureSize", - NULL - }; - - static const char* s_textureArray[] = - { - "sampler2DArray", - "texture2DArray", - "texture2DArrayLod", - "shadow2DArray", - NULL - }; - - static const char* s_ARB_texture_multisample[] = - { - "sampler2DMS", - "isampler2DMS", - "usampler2DMS", - NULL - }; - - static const char* s_texelFetch[] = - { - "texelFetch", - "texelFetchOffset", - NULL - }; - - static const char* s_bitsToEncoders[] = - { - "floatBitsToUint", - "floatBitsToInt", - "intBitsToFloat", - "uintBitsToFloat", - NULL - }; - - static const char* s_unsignedVecs[] = - { - "uvec2", - "uvec3", - "uvec4", - NULL + static const char *s_ARB_shader_viewport_layer_array[] = + { + "gl_ViewportIndex", + "gl_Layer", + NULL}; + + static const char *s_ARB_gpu_shader5[] = + { + "bitfieldReverse", + "floatBitsToInt", + "floatBitsToUint", + "intBitsToFloat", + "uintBitsToFloat", + NULL}; + + static const char *s_ARB_shading_language_packing[] = + { + "packHalf2x16", + "unpackHalf2x16", + NULL}; + + static const char *s_130[] = + { + "uint", + "uint2", + "uint3", + "uint4", + "isampler2D", + "usampler2D", + "isampler3D", + "usampler3D", + "isamplerCube", + "usamplerCube", + "textureSize", + NULL}; + + static const char *s_textureArray[] = + { + "sampler2DArray", + "texture2DArray", + "texture2DArrayLod", + "shadow2DArray", + NULL}; + + static const char *s_ARB_texture_multisample[] = + { + "sampler2DMS", + "isampler2DMS", + "usampler2DMS", + NULL}; + + static const char *s_texelFetch[] = + { + "texelFetch", + "texelFetchOffset", + NULL}; + + static const char *s_bitsToEncoders[] = + { + "floatBitsToUint", + "floatBitsToInt", + "intBitsToFloat", + "uintBitsToFloat", + NULL}; + + static const char *s_integerVecs[] = + { + "ivec2", + "uvec2", + "ivec3", + "uvec3", + "ivec4", + "uvec4", + NULL}; + + const char *s_uniformTypeName[] = + { + "int", + "int", + NULL, + NULL, + "vec4", + "float4", + "mat3", + "float3x3", + "mat4", + "float4x4", }; - - const char* s_uniformTypeName[] = - { - "int", "int", - NULL, NULL, - "vec4", "float4", - "mat3", "float3x3", - "mat4", "float4x4", - }; - BX_STATIC_ASSERT(BX_COUNTOF(s_uniformTypeName) == UniformType::Count*2); - - static const char* s_allowedVertexShaderInputs[] = - { - "a_position", - "a_normal", - "a_tangent", - "a_bitangent", - "a_color0", - "a_color1", - "a_color2", - "a_color3", - "a_indices", - "a_weight", - "a_texcoord0", - "a_texcoord1", - "a_texcoord2", - "a_texcoord3", - "a_texcoord4", - "a_texcoord5", - "a_texcoord6", - "a_texcoord7", - "i_data0", - "i_data1", - "i_data2", - "i_data3", - "i_data4", - NULL - }; - - void fatal(const char* _filePath, uint16_t _line, Fatal::Enum _code, const char* _format, ...) + BX_STATIC_ASSERT(BX_COUNTOF(s_uniformTypeName) == UniformType::Count * 2); + + static const char *s_allowedVertexShaderInputs[] = + { + "a_position", + "a_normal", + "a_tangent", + "a_bitangent", + "a_color0", + "a_color1", + "a_color2", + "a_color3", + "a_indices", + "a_weight", + "a_texcoord0", + "a_texcoord1", + "a_texcoord2", + "a_texcoord3", + "a_texcoord4", + "a_texcoord5", + "a_texcoord6", + "a_texcoord7", + "i_data0", + "i_data1", + "i_data2", + "i_data3", + "i_data4", + NULL}; + + void fatal(const char *_filePath, uint16_t _line, Fatal::Enum _code, const char *_format, ...) { BX_UNUSED(_filePath, _line, _code); @@ -353,7 +345,7 @@ namespace bgfx abort(); } - void trace(const char* _filePath, uint16_t _line, const char* _format, ...) + void trace(const char *_filePath, uint16_t _line, const char *_format, ...) { BX_UNUSED(_filePath, _line); @@ -365,91 +357,59 @@ namespace bgfx va_end(argList); } Options::Options() - : shaderType(' ') - , disasm(false) - , raw(false) - , preprocessOnly(false) - , depends(false) - , debugInformation(false) - , avoidFlowControl(false) - , noPreshader(false) - , partialPrecision(false) - , preferFlowControl(false) - , backwardsCompatibility(false) - , warningsAreErrors(false) - , keepIntermediate(false) - , optimize(false) - , optimizationLevel(3) + : shaderType(' '), disasm(false), raw(false), preprocessOnly(false), depends(false), debugInformation(false), avoidFlowControl(false), noPreshader(false), partialPrecision(false), preferFlowControl(false), backwardsCompatibility(false), warningsAreErrors(false), keepIntermediate(false), optimize(false), optimizationLevel(3) { } void Options::dump() { BX_TRACE("Options:\n" - "\t shaderType: %c\n" - "\t platform: %s\n" - "\t profile: %s\n" - "\t inputFile: %s\n" - "\t outputFile: %s\n" - "\t disasm: %s\n" - "\t raw: %s\n" - "\t preprocessOnly: %s\n" - "\t depends: %s\n" - "\t debugInformation: %s\n" - "\t avoidFlowControl: %s\n" - "\t noPreshader: %s\n" - "\t partialPrecision: %s\n" - "\t preferFlowControl: %s\n" - "\t backwardsCompatibility: %s\n" - "\t warningsAreErrors: %s\n" - "\t keepIntermediate: %s\n" - "\t optimize: %s\n" - "\t optimizationLevel: %d\n" - - , shaderType - , platform.c_str() - , profile.c_str() - , inputFilePath.c_str() - , outputFilePath.c_str() - , disasm ? "true" : "false" - , raw ? "true" : "false" - , preprocessOnly ? "true" : "false" - , depends ? "true" : "false" - , debugInformation ? "true" : "false" - , avoidFlowControl ? "true" : "false" - , noPreshader ? "true" : "false" - , partialPrecision ? "true" : "false" - , preferFlowControl ? "true" : "false" - , backwardsCompatibility ? "true" : "false" - , warningsAreErrors ? "true" : "false" - , keepIntermediate ? "true" : "false" - , optimize ? "true" : "false" - , optimizationLevel - ); + "\t shaderType: %c\n" + "\t platform: %s\n" + "\t profile: %s\n" + "\t inputFile: %s\n" + "\t outputFile: %s\n" + "\t disasm: %s\n" + "\t raw: %s\n" + "\t preprocessOnly: %s\n" + "\t depends: %s\n" + "\t debugInformation: %s\n" + "\t avoidFlowControl: %s\n" + "\t noPreshader: %s\n" + "\t partialPrecision: %s\n" + "\t preferFlowControl: %s\n" + "\t backwardsCompatibility: %s\n" + "\t warningsAreErrors: %s\n" + "\t keepIntermediate: %s\n" + "\t optimize: %s\n" + "\t optimizationLevel: %d\n" + + , + shaderType, platform.c_str(), profile.c_str(), inputFilePath.c_str(), outputFilePath.c_str(), disasm ? "true" : "false", raw ? "true" : "false", preprocessOnly ? "true" : "false", depends ? "true" : "false", debugInformation ? "true" : "false", avoidFlowControl ? "true" : "false", noPreshader ? "true" : "false", partialPrecision ? "true" : "false", preferFlowControl ? "true" : "false", backwardsCompatibility ? "true" : "false", warningsAreErrors ? "true" : "false", keepIntermediate ? "true" : "false", optimize ? "true" : "false", optimizationLevel); for (size_t ii = 0; ii < includeDirs.size(); ++ii) { - BX_TRACE("\t include :%s\n", includeDirs[ii].c_str() ); + BX_TRACE("\t include :%s\n", includeDirs[ii].c_str()); } for (size_t ii = 0; ii < defines.size(); ++ii) { - BX_TRACE("\t define :%s\n", defines[ii].c_str() ); + BX_TRACE("\t define :%s\n", defines[ii].c_str()); } for (size_t ii = 0; ii < dependencies.size(); ++ii) { - BX_TRACE("\t dependency :%s\n", dependencies[ii].c_str() ); + BX_TRACE("\t dependency :%s\n", dependencies[ii].c_str()); } } - const char* interpolationDx11(const char* _glsl) + const char *interpolationDx11(const char *_glsl) { - if (0 == bx::strCmp(_glsl, "smooth") ) + if (0 == bx::strCmp(_glsl, "smooth")) { return "linear"; } - else if (0 == bx::strCmp(_glsl, "flat") ) + else if (0 == bx::strCmp(_glsl, "flat")) { return "nointerpolation"; } @@ -457,9 +417,9 @@ namespace bgfx return _glsl; // centroid, noperspective } - const char* getUniformTypeName(UniformType::Enum _enum) + const char *getUniformTypeName(UniformType::Enum _enum) { - uint32_t idx = _enum & ~(kUniformFragmentBit|kUniformSamplerBit); + uint32_t idx = _enum & ~(kUniformFragmentBit | kUniformSamplerBit); if (idx < UniformType::Count) { return s_uniformTypeName[idx]; @@ -468,33 +428,32 @@ namespace bgfx return "Unknown uniform type?!"; } - UniformType::Enum nameToUniformTypeEnum(const char* _name) + UniformType::Enum nameToUniformTypeEnum(const char *_name) { - for (uint32_t ii = 0; ii < UniformType::Count*2; ++ii) + for (uint32_t ii = 0; ii < UniformType::Count * 2; ++ii) { - if (NULL != s_uniformTypeName[ii] - && 0 == bx::strCmp(_name, s_uniformTypeName[ii]) ) + if (NULL != s_uniformTypeName[ii] && 0 == bx::strCmp(_name, s_uniformTypeName[ii])) { - return UniformType::Enum(ii/2); + return UniformType::Enum(ii / 2); } } return UniformType::Count; } - int32_t writef(bx::WriterI* _writer, const char* _format, ...) + int32_t writef(bx::WriterI *_writer, const char *_format, ...) { va_list argList; va_start(argList, _format); char temp[2048]; - char* out = temp; + char *out = temp; int32_t max = sizeof(temp); int32_t len = bx::vsnprintf(out, max, _format, argList); if (len > max) { - out = (char*)alloca(len); + out = (char *)alloca(len); len = bx::vsnprintf(out, len, _format, argList); } @@ -508,7 +467,7 @@ namespace bgfx class Bin2cWriter : public bx::FileWriter { public: - Bin2cWriter(const bx::StringView& _name) + Bin2cWriter(const bx::StringView &_name) : m_name(_name) { } @@ -523,10 +482,10 @@ namespace bgfx return bx::FileWriter::close(); } - virtual int32_t write(const void* _data, int32_t _size, bx::Error*) override + virtual int32_t write(const void *_data, int32_t _size, bx::Error *) override { - const char* data = (const char*)_data; - m_buffer.insert(m_buffer.end(), data, data+_size); + const char *data = (const char *)_data; + m_buffer.insert(m_buffer.end(), data, data + _size); return _size; } @@ -536,23 +495,23 @@ namespace bgfx #define HEX_DUMP_WIDTH 16 #define HEX_DUMP_SPACE_WIDTH 96 #define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s" - const uint8_t* data = &m_buffer[0]; + const uint8_t *data = &m_buffer[0]; uint32_t size = (uint32_t)m_buffer.size(); outf("static const uint8_t %.*s[%d] =\n{\n", m_name.getLength(), m_name.getPtr(), size); if (NULL != data) { - char hex[HEX_DUMP_SPACE_WIDTH+1]; - char ascii[HEX_DUMP_WIDTH+1]; + char hex[HEX_DUMP_SPACE_WIDTH + 1]; + char ascii[HEX_DUMP_WIDTH + 1]; uint32_t hexPos = 0; uint32_t asciiPos = 0; for (uint32_t ii = 0; ii < size; ++ii) { - bx::snprintf(&hex[hexPos], sizeof(hex)-hexPos, "0x%02x, ", data[asciiPos]); + bx::snprintf(&hex[hexPos], sizeof(hex) - hexPos, "0x%02x, ", data[asciiPos]); hexPos += 6; - ascii[asciiPos] = isprint(data[asciiPos]) && data[asciiPos] != '\\' && data[asciiPos] != '\t' ? data[asciiPos] : '.'; + ascii[asciiPos] = isprint(data[asciiPos]) && data[asciiPos] != '\\' && data[asciiPos] != '\t' ? data[asciiPos] : '.'; asciiPos++; if (HEX_DUMP_WIDTH == asciiPos) @@ -578,18 +537,18 @@ namespace bgfx #undef HEX_DUMP_FORMAT } - int32_t outf(const char* _format, ...) + int32_t outf(const char *_format, ...) { va_list argList; va_start(argList, _format); char temp[2048]; - char* out = temp; + char *out = temp; int32_t max = sizeof(temp); int32_t len = bx::vsnprintf(out, max, _format, argList); if (len > max) { - out = (char*)alloca(len); + out = (char *)alloca(len); len = bx::vsnprintf(out, len, _format, argList); } @@ -621,31 +580,28 @@ namespace bgfx { public: File() - : m_data(NULL) - , m_size(0) + : m_data(NULL), m_size(0) { } ~File() { - delete [] m_data; + delete[] m_data; } - void load(const bx::FilePath& _filePath) + void load(const bx::FilePath &_filePath) { bx::FileReader reader; - if (bx::open(&reader, _filePath) ) + if (bx::open(&reader, _filePath)) { m_size = (uint32_t)bx::getSize(&reader); - m_data = new char[m_size+1]; + m_data = new char[m_size + 1]; m_size = (uint32_t)bx::read(&reader, m_data, m_size, bx::ErrorAssert{}); bx::close(&reader); - if (m_data[0] == '\xef' - && m_data[1] == '\xbb' - && m_data[2] == '\xbf') + if (m_data[0] == '\xef' && m_data[1] == '\xbb' && m_data[2] == '\xbf') { - bx::memMove(m_data, &m_data[3], m_size-3); + bx::memMove(m_data, &m_data[3], m_size - 3); m_size -= 3; } @@ -653,7 +609,7 @@ namespace bgfx } } - const char* getData() const + const char *getData() const { return m_data; } @@ -664,24 +620,24 @@ namespace bgfx } private: - char* m_data; + char *m_data; uint32_t m_size; }; - char* strInsert(char* _str, const char* _insert) + char *strInsert(char *_str, const char *_insert) { uint32_t len = bx::strLen(_insert); - bx::memMove(&_str[len], _str, bx::strLen(_str) ); + bx::memMove(&_str[len], _str, bx::strLen(_str)); bx::memCopy(_str, _insert, len); return _str + len; } - void strReplace(char* _str, const char* _find, const char* _replace) + void strReplace(char *_str, const char *_find, const char *_replace) { const int32_t len = bx::strLen(_find); - char* replace = (char*)alloca(len+1); - bx::strCopy(replace, len+1, _replace); + char *replace = (char *)alloca(len + 1); + bx::strCopy(replace, len + 1, _replace); for (int32_t ii = bx::strLen(replace); ii < len; ++ii) { replace[ii] = ' '; @@ -689,22 +645,19 @@ namespace bgfx replace[len] = '\0'; BX_ASSERT(len >= bx::strLen(_replace), ""); - for (bx::StringView ptr = bx::strFind(_str, _find) - ; !ptr.isEmpty() - ; ptr = bx::strFind(ptr.getPtr() + len, _find) - ) + for (bx::StringView ptr = bx::strFind(_str, _find); !ptr.isEmpty(); ptr = bx::strFind(ptr.getPtr() + len, _find)) { - bx::memCopy(const_cast(ptr.getPtr() ), replace, len); + bx::memCopy(const_cast(ptr.getPtr()), replace, len); } } - void strNormalizeEol(char* _str) + void strNormalizeEol(char *_str) { strReplace(_str, "\r\n", "\n"); - strReplace(_str, "\r", "\n"); + strReplace(_str, "\r", "\n"); } - void printCode(const char* _code, int32_t _line, int32_t _start, int32_t _end, int32_t _column) + void printCode(const char *_code, int32_t _line, int32_t _start, int32_t _end, int32_t _column) { bx::printf("Code:\n---\n"); @@ -718,7 +671,7 @@ namespace bgfx if (_line == line) { bx::printf("\n"); - bx::printf(">>> %3d: %.*s\n", line, strLine.getLength(), strLine.getPtr() ); + bx::printf(">>> %3d: %.*s\n", line, strLine.getLength(), strLine.getPtr()); if (-1 != _column) { bx::printf(">>> %3d: %*s\n", _column, _column, "^"); @@ -727,7 +680,7 @@ namespace bgfx } else { - bx::printf(" %3d: %.*s\n", line, strLine.getLength(), strLine.getPtr() ); + bx::printf(" %3d: %.*s\n", line, strLine.getLength(), strLine.getPtr()); } } } @@ -735,10 +688,10 @@ namespace bgfx bx::printf("---\n"); } - void writeFile(const char* _filePath, const void* _data, int32_t _size) + void writeFile(const char *_filePath, const void *_data, int32_t _size) { bx::FileWriter out; - if (bx::open(&out, _filePath) ) + if (bx::open(&out, _filePath)) { bx::write(&out, _data, _size, bx::ErrorAssert{}); bx::close(&out); @@ -747,38 +700,35 @@ namespace bgfx struct Preprocessor { - Preprocessor(const char* _filePath, bool _essl, bx::WriterI* _messageWriter) - : m_tagptr(m_tags) - , m_scratchPos(0) - , m_fgetsPos(0) - , m_messageWriter(_messageWriter) + Preprocessor(const char *_filePath, bool _essl, bx::WriterI *_messageWriter) + : m_tagptr(m_tags), m_scratchPos(0), m_fgetsPos(0), m_messageWriter(_messageWriter) { m_tagptr->tag = FPPTAG_USERDATA; m_tagptr->data = this; m_tagptr++; m_tagptr->tag = FPPTAG_DEPENDS; - m_tagptr->data = (void*)fppDepends; + m_tagptr->data = (void *)fppDepends; m_tagptr++; m_tagptr->tag = FPPTAG_INPUT; - m_tagptr->data = (void*)fppInput; + m_tagptr->data = (void *)fppInput; m_tagptr++; m_tagptr->tag = FPPTAG_OUTPUT; - m_tagptr->data = (void*)fppOutput; + m_tagptr->data = (void *)fppOutput; m_tagptr++; m_tagptr->tag = FPPTAG_ERROR; - m_tagptr->data = (void*)fppError; + m_tagptr->data = (void *)fppError; m_tagptr++; m_tagptr->tag = FPPTAG_SHOWVERSION; - m_tagptr->data = (void*)0; + m_tagptr->data = (void *)0; m_tagptr++; m_tagptr->tag = FPPTAG_LINE; - m_tagptr->data = (void*)0; + m_tagptr->data = (void *)0; m_tagptr++; m_tagptr->tag = FPPTAG_INPUT_NAME; @@ -791,30 +741,26 @@ namespace bgfx } } - void setDefine(const char* _define) + void setDefine(const char *_define) { m_tagptr->tag = FPPTAG_DEFINE; m_tagptr->data = scratch(_define); m_tagptr++; } - void setDefaultDefine(const char* _name) + void setDefaultDefine(const char *_name) { char temp[1024]; - bx::snprintf(temp, BX_COUNTOF(temp) - , "#ifndef %s\n" - "# define %s 0\n" - "#endif // %s\n" - "\n" - , _name - , _name - , _name - ); + bx::snprintf(temp, BX_COUNTOF(temp), "#ifndef %s\n" + "# define %s 0\n" + "#endif // %s\n" + "\n", + _name, _name, _name); m_default += temp; } - void writef(const char* _format, ...) + void writef(const char *_format, ...) { va_list argList; va_start(argList, _format); @@ -822,20 +768,17 @@ namespace bgfx va_end(argList); } - void addInclude(const char* _includeDir) + void addInclude(const char *_includeDir) { - char* start = scratch(_includeDir); + char *start = scratch(_includeDir); - for (bx::StringView split = bx::strFind(start, ';') - ; !split.isEmpty() - ; split = bx::strFind(start, ';') - ) + for (bx::StringView split = bx::strFind(start, ';'); !split.isEmpty(); split = bx::strFind(start, ';')) { - *const_cast(split.getPtr() ) = '\0'; + *const_cast(split.getPtr()) = '\0'; m_tagptr->tag = FPPTAG_INCLUDE_DIR; m_tagptr->data = start; m_tagptr++; - start = const_cast(split.getPtr() ) + 1; + start = const_cast(split.getPtr()) + 1; } m_tagptr->tag = FPPTAG_INCLUDE_DIR; @@ -843,13 +786,13 @@ namespace bgfx m_tagptr++; } - void addDependency(const char* _fileName) + void addDependency(const char *_fileName) { m_depends += " \\\n "; m_depends += _fileName; } - bool run(const char* _input) + bool run(const char *_input) { m_fgetsPos = 0; @@ -857,15 +800,15 @@ namespace bgfx m_input = m_default; m_input += "\n\n"; - int32_t len = bx::strLen(_input)+1; - char* temp = new char[len]; + int32_t len = bx::strLen(_input) + 1; + char *temp = new char[len]; bx::StringView normalized = bx::normalizeEolLf(temp, len, _input); std::string str; - str.assign(normalized.getPtr(), normalized.getTerm() ); + str.assign(normalized.getPtr(), normalized.getTerm()); m_input += str; - delete [] temp; + delete[] temp; - fppTag* tagptr = m_tagptr; + fppTag *tagptr = m_tagptr; tagptr->tag = FPPTAG_END; tagptr->data = 0; @@ -876,10 +819,10 @@ namespace bgfx return 0 == result; } - char* fgets(char* _buffer, int _size) + char *fgets(char *_buffer, int _size) { int ii = 0; - for (char ch = m_input[m_fgetsPos]; m_fgetsPos < m_input.size() && ii < _size-1; ch = m_input[++m_fgetsPos]) + for (char ch = m_input[m_fgetsPos]; m_fgetsPos < m_input.size() && ii < _size - 1; ch = m_input[++m_fgetsPos]) { _buffer[ii++] = ch; @@ -894,88 +837,87 @@ namespace bgfx return NULL; } - static void fppDepends(char* _fileName, void* _userData) + static void fppDepends(char *_fileName, void *_userData) { - Preprocessor* thisClass = (Preprocessor*)_userData; + Preprocessor *thisClass = (Preprocessor *)_userData; thisClass->addDependency(_fileName); } - static char* fppInput(char* _buffer, int _size, void* _userData) + static char *fppInput(char *_buffer, int _size, void *_userData) { - Preprocessor* thisClass = (Preprocessor*)_userData; + Preprocessor *thisClass = (Preprocessor *)_userData; return thisClass->fgets(_buffer, _size); } - static void fppOutput(int _ch, void* _userData) + static void fppOutput(int _ch, void *_userData) { - Preprocessor* thisClass = (Preprocessor*)_userData; + Preprocessor *thisClass = (Preprocessor *)_userData; thisClass->m_preprocessed += char(_ch); } - static void fppError(void* _userData, char* _format, va_list _vargs) + static void fppError(void *_userData, char *_format, va_list _vargs) { bx::ErrorAssert err; - Preprocessor* thisClass = (Preprocessor*)_userData; + Preprocessor *thisClass = (Preprocessor *)_userData; bx::write(thisClass->m_messageWriter, _format, _vargs, &err); } - char* scratch(const char* _str) + char *scratch(const char *_str) { - char* result = &m_scratch[m_scratchPos]; - bx::strCopy(result, uint32_t(sizeof(m_scratch)-m_scratchPos), _str); - m_scratchPos += (uint32_t)bx::strLen(_str)+1; + char *result = &m_scratch[m_scratchPos]; + bx::strCopy(result, uint32_t(sizeof(m_scratch) - m_scratchPos), _str); + m_scratchPos += (uint32_t)bx::strLen(_str) + 1; return result; } fppTag m_tags[MAX_TAGS]; - fppTag* m_tagptr; + fppTag *m_tagptr; std::string m_depends; std::string m_default; std::string m_input; std::string m_preprocessed; - char m_scratch[16<<10]; + char m_scratch[16 << 10]; uint32_t m_scratchPos; uint32_t m_fgetsPos; - bx::WriterI* m_messageWriter; + bx::WriterI *m_messageWriter; }; typedef std::vector InOut; - uint32_t parseInOut(InOut& _inout, const bx::StringView& _str) + uint32_t parseInOut(InOut &_inout, const bx::StringView &_str) { uint32_t hash = 0; bx::StringView str = bx::strLTrimSpace(_str); - if (!str.isEmpty() ) + if (!str.isEmpty()) { bx::StringView delim; do { delim = bx::strFind(str, ','); - if (delim.isEmpty() ) + if (delim.isEmpty()) { delim = bx::strFind(str, ' '); } - const bx::StringView token(bx::strRTrim(bx::StringView(str.getPtr(), delim.getPtr() ), " ") ); + const bx::StringView token(bx::strRTrim(bx::StringView(str.getPtr(), delim.getPtr()), " ")); - if (!token.isEmpty() ) + if (!token.isEmpty()) { - _inout.push_back(std::string(token.getPtr(), token.getTerm() ) ); - str = bx::strLTrimSpace(bx::StringView(delim.getPtr() + 1, str.getTerm() ) ); + _inout.push_back(std::string(token.getPtr(), token.getTerm())); + str = bx::strLTrimSpace(bx::StringView(delim.getPtr() + 1, str.getTerm())); } - } - while (!delim.isEmpty() ); + } while (!delim.isEmpty()); - std::sort(_inout.begin(), _inout.end() ); + std::sort(_inout.begin(), _inout.end()); bx::HashMurmur2A murmur; murmur.begin(); for (InOut::const_iterator it = _inout.begin(), itEnd = _inout.end(); it != itEnd; ++it) { - murmur.add(it->c_str(), (uint32_t)it->size() ); + murmur.add(it->c_str(), (uint32_t)it->size()); } hash = murmur.end(); } @@ -983,7 +925,7 @@ namespace bgfx return hash; } - void addFragData(Preprocessor& _preprocessor, char* _data, uint32_t _idx, bool _comma) + void addFragData(Preprocessor &_preprocessor, char *_data, uint32_t _idx, bool _comma) { char find[32]; bx::snprintf(find, sizeof(find), "gl_FragData[%d]", _idx); @@ -994,14 +936,10 @@ namespace bgfx strReplace(_data, find, replace); _preprocessor.writef( - " \\\n\t%sout vec4 bgfx_FragData%d : SV_TARGET%d" - , _comma ? ", " : " " - , _idx - , _idx - ); + " \\\n\t%sout vec4 bgfx_FragData%d : SV_TARGET%d", _comma ? ", " : " ", _idx, _idx); } - void voidFragData(char* _data, uint32_t _idx) + void voidFragData(char *_data, uint32_t _idx) { char find[32]; bx::snprintf(find, sizeof(find), "gl_FragData[%d]", _idx); @@ -1009,13 +947,13 @@ namespace bgfx strReplace(_data, find, "bgfx_VoidFrag"); } - bx::StringView baseName(const bx::StringView& _filePath) + bx::StringView baseName(const bx::StringView &_filePath) { bx::FilePath fp(_filePath); - return bx::strFind(_filePath, fp.getBaseName() ); + return bx::strFind(_filePath, fp.getBaseName()); } - void help(const char* _error = NULL) + void help(const char *_error = NULL) { if (NULL != _error) { @@ -1023,104 +961,98 @@ namespace bgfx } bx::printf( - "shaderc, bgfx shader compiler tool, version %d.%d.%d.\n" - "Copyright 2011-2024 Branimir Karadzic. All rights reserved.\n" - "License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE\n\n" - , BGFX_SHADERC_VERSION_MAJOR - , BGFX_SHADERC_VERSION_MINOR - , BGFX_API_VERSION - ); + "shaderc, bgfx shader compiler tool, version %d.%d.%d.\n" + "Copyright 2011-2024 Branimir Karadzic. All rights reserved.\n" + "License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE\n\n", + BGFX_SHADERC_VERSION_MAJOR, BGFX_SHADERC_VERSION_MINOR, BGFX_API_VERSION); bx::printf( - "Usage: shaderc -f -o --type --platform \n" - - "\n" - "Options:\n" - " -h, --help Display this help and exit.\n" - " -v, --version Output version information and exit.\n" - " -f Input's file path.\n" - " -i Include path. (for multiple paths use -i multiple times)\n" - " -o Output's file path.\n" - " --stdout Output to console.\n" - " --bin2c [array name] Generate C header file. If array name is not specified base file name will be used as name.\n" - " --depends Generate makefile style depends file.\n" - " --platform Target platform.\n" - " android\n" - " asm.js\n" - " ios\n" - " linux\n" - " orbis\n" - " osx\n" - " windows\n" - " -p, --profile Shader model. Defaults to GLSL.\n" - ); + "Usage: shaderc -f -o --type --platform \n" + + "\n" + "Options:\n" + " -h, --help Display this help and exit.\n" + " -v, --version Output version information and exit.\n" + " -f Input's file path.\n" + " -i Include path. (for multiple paths use -i multiple times)\n" + " -o Output's file path.\n" + " --stdout Output to console.\n" + " --bin2c [array name] Generate C header file. If array name is not specified base file name will be used as name.\n" + " --depends Generate makefile style depends file.\n" + " --platform Target platform.\n" + " android\n" + " asm.js\n" + " ios\n" + " linux\n" + " orbis\n" + " osx\n" + " windows\n" + " -p, --profile Shader model. Defaults to GLSL.\n"); { ShadingLang::Enum lang = ShadingLang::Count; for (uint32_t ii = 0; ii < BX_COUNTOF(s_profiles); ++ii) { - const Profile& profile = s_profiles[ii]; + const Profile &profile = s_profiles[ii]; if (lang != profile.lang) { lang = profile.lang; bx::printf("\n"); - bx::printf(" %-20S %s\n", &profile.name, getName(profile.lang) ); + bx::printf(" %-20S %s\n", &profile.name, getName(profile.lang)); } else { bx::printf(" %S\n", &profile.name); } - } } bx::printf( - " --preprocess Only pre-process.\n" - " --define Add defines to preprocessor. (Semicolon-separated)\n" - " --raw Do not process shader. No preprocessor, and no glsl-optimizer. (GLSL only)\n" - " --type Shader type. Can be 'vertex', 'fragment, or 'compute'.\n" - " --varyingdef varying.def.sc's file path.\n" - " --verbose Be verbose.\n" - - "\n" - "(Vulkan, DirectX and Metal):\n" - - "\n" - " --debug Debug information.\n" - - "\n" - "(DirectX only):\n" - - "\n" - " --disasm Disassemble compiled shader.\n" - " -O Set optimization level. Can be 0 to 3.\n" - " --Werror Treat warnings as errors.\n" - - "\n" - "For additional information, see https://github.com/bkaradzic/bgfx\n" - ); + " --preprocess Only pre-process.\n" + " --define Add defines to preprocessor. (Semicolon-separated)\n" + " --raw Do not process shader. No preprocessor, and no glsl-optimizer. (GLSL only)\n" + " --type Shader type. Can be 'vertex', 'fragment, or 'compute'.\n" + " --varyingdef varying.def.sc's file path.\n" + " --verbose Be verbose.\n" + + "\n" + "(Vulkan, DirectX and Metal):\n" + + "\n" + " --debug Debug information.\n" + + "\n" + "(DirectX only):\n" + + "\n" + " --disasm Disassemble compiled shader.\n" + " -O Set optimization level. Can be 0 to 3.\n" + " --Werror Treat warnings as errors.\n" + + "\n" + "For additional information, see https://github.com/bkaradzic/bgfx\n"); } - bx::StringView nextWord(bx::StringView& _parse) + bx::StringView nextWord(bx::StringView &_parse) { - bx::StringView word = bx::strWord(bx::strLTrimSpace(_parse) ); - _parse = bx::strLTrimSpace(bx::StringView(word.getTerm(), _parse.getTerm() ) ); + bx::StringView word = bx::strWord(bx::strLTrimSpace(_parse)); + _parse = bx::strLTrimSpace(bx::StringView(word.getTerm(), _parse.getTerm())); return word; } - bool compileShader(const char* _varying, const char* _comment, char* _shader, uint32_t _shaderLen, const Options& _options, bx::WriterI* _shaderWriter, bx::WriterI* _messageWriter) + bool compileShader(const char *_varying, const char *_comment, char *_shader, uint32_t _shaderLen, const Options &_options, bx::WriterI *_shaderWriter, bx::WriterI *_messageWriter) { bx::ErrorAssert messageErr; uint32_t profileId = 0; - const bx::StringView profileOpt(_options.profile.c_str() ); - if (!profileOpt.isEmpty() ) + const bx::StringView profileOpt(_options.profile.c_str()); + if (!profileOpt.isEmpty()) { const uint32_t count = BX_COUNTOF(s_profiles); for (profileId = 0; profileId < count; ++profileId) { - if (0 == bx::strCmp(profileOpt, s_profiles[profileId].name) ) + if (0 == bx::strCmp(profileOpt, s_profiles[profileId].name)) { break; } @@ -1138,28 +1070,29 @@ namespace bgfx return false; } - const Profile* profile = &s_profiles[profileId]; + const Profile *profile = &s_profiles[profileId]; Preprocessor preprocessor(_options.inputFilePath.c_str(), profile->lang == ShadingLang::ESSL, _messageWriter); for (size_t ii = 0; ii < _options.includeDirs.size(); ++ii) { - preprocessor.addInclude(_options.includeDirs[ii].c_str() ); + preprocessor.addInclude(_options.includeDirs[ii].c_str()); } for (size_t ii = 0; ii < _options.defines.size(); ++ii) { - preprocessor.setDefine(_options.defines[ii].c_str() ); + preprocessor.setDefine(_options.defines[ii].c_str()); } for (size_t ii = 0; ii < _options.dependencies.size(); ++ii) { - preprocessor.addDependency(_options.dependencies[ii].c_str() ); + preprocessor.addDependency(_options.dependencies[ii].c_str()); } preprocessor.setDefaultDefine("BX_PLATFORM_ANDROID"); preprocessor.setDefaultDefine("BX_PLATFORM_EMSCRIPTEN"); preprocessor.setDefaultDefine("BX_PLATFORM_IOS"); + preprocessor.setDefaultDefine("BX_PLATFORM_VISIONOS"); preprocessor.setDefaultDefine("BX_PLATFORM_LINUX"); preprocessor.setDefaultDefine("BX_PLATFORM_OSX"); preprocessor.setDefaultDefine("BX_PLATFORM_PS4"); @@ -1177,26 +1110,20 @@ namespace bgfx preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_VERTEX"); char glslDefine[128]; - if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { - bx::snprintf(glslDefine, BX_COUNTOF(glslDefine) - , "BGFX_SHADER_LANGUAGE_GLSL=%d" - , profile->id - ); + bx::snprintf(glslDefine, BX_COUNTOF(glslDefine), "BGFX_SHADER_LANGUAGE_GLSL=%d", profile->id); } char hlslDefine[128]; if (profile->lang == ShadingLang::HLSL) { - bx::snprintf(hlslDefine, BX_COUNTOF(hlslDefine) - , "BGFX_SHADER_LANGUAGE_HLSL=%d" - , profile->id); + bx::snprintf(hlslDefine, BX_COUNTOF(hlslDefine), "BGFX_SHADER_LANGUAGE_HLSL=%d", profile->id); } - const char* platform = _options.platform.c_str(); + const char *platform = _options.platform.c_str(); - if (0 == bx::strCmpI(platform, "android") ) + if (0 == bx::strCmpI(platform, "android")) { preprocessor.setDefine("BX_PLATFORM_ANDROID=1"); if (profile->lang == ShadingLang::SpirV) @@ -1208,12 +1135,12 @@ namespace bgfx preprocessor.setDefine(glslDefine); } } - else if (0 == bx::strCmpI(platform, "asm.js") ) + else if (0 == bx::strCmpI(platform, "asm.js")) { preprocessor.setDefine("BX_PLATFORM_EMSCRIPTEN=1"); preprocessor.setDefine(glslDefine); } - else if (0 == bx::strCmpI(platform, "linux") ) + else if (0 == bx::strCmpI(platform, "linux")) { preprocessor.setDefine("BX_PLATFORM_LINUX=1"); if (profile->lang == ShadingLang::SpirV) @@ -1225,12 +1152,19 @@ namespace bgfx preprocessor.setDefine(glslDefine); } } - else if (0 == bx::strCmpI(platform, "ios") || (0 == bx::strCmpI(platform, "osx")) ) + else if ( + 0 == bx::strCmpI(platform, "ios") || + 0 == bx::strCmpI(platform, "osx") || + 0 == bx::strCmpI(platform, "visionos")) { if (0 == bx::strCmpI(platform, "osx")) { preprocessor.setDefine("BX_PLATFORM_OSX=1"); } + else if (0 == bx::strCmpI(platform, "visionos")) + { + preprocessor.setDefine("BX_PLATFORM_VISIONOS=1"); + } else { preprocessor.setDefine("BX_PLATFORM_IOS=1"); @@ -1242,22 +1176,17 @@ namespace bgfx } char temp[32]; bx::snprintf( - temp - , sizeof(temp) - , "BGFX_SHADER_LANGUAGE_METAL=%d" - , (profile->lang == ShadingLang::Metal) ? profile->id : 0 - ); + temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_METAL=%d", (profile->lang == ShadingLang::Metal) ? profile->id : 0); preprocessor.setDefine(temp); } - else if (0 == bx::strCmpI(platform, "windows") ) + else if (0 == bx::strCmpI(platform, "windows")) { preprocessor.setDefine("BX_PLATFORM_WINDOWS=1"); if (profile->lang == ShadingLang::HLSL) { preprocessor.setDefine(hlslDefine); } - else if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + else if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { preprocessor.setDefine(glslDefine); } @@ -1266,7 +1195,7 @@ namespace bgfx preprocessor.setDefine("BGFX_SHADER_LANGUAGE_SPIRV=1"); } } - else if (0 == bx::strCmpI(platform, "orbis") ) + else if (0 == bx::strCmpI(platform, "orbis")) { preprocessor.setDefine("BX_PLATFORM_PS4=1"); preprocessor.setDefine("BGFX_SHADER_LANGUAGE_PSSL=1"); @@ -1278,8 +1207,7 @@ namespace bgfx { preprocessor.setDefine(hlslDefine); } - else if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + else if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { preprocessor.setDefine(glslDefine); } @@ -1318,39 +1246,32 @@ namespace bgfx bool usesInterpolationQualifiers = false; - while (!parse.isEmpty() ) + while (!parse.isEmpty()) { parse = bx::strLTrimSpace(parse); bx::StringView eol = bx::strFind(parse, ';'); - if (eol.isEmpty() ) + if (eol.isEmpty()) { eol = bx::strFindEol(parse); } - if (!eol.isEmpty() ) + if (!eol.isEmpty()) { - eol.set(eol.getPtr() + 1, parse.getTerm() ); + eol.set(eol.getPtr() + 1, parse.getTerm()); bx::StringView precision; bx::StringView interpolation; bx::StringView typen = nextWord(parse); - if (0 == bx::strCmp(typen, "lowp", 4) - || 0 == bx::strCmp(typen, "mediump", 7) - || 0 == bx::strCmp(typen, "highp", 5) ) + if (0 == bx::strCmp(typen, "lowp", 4) || 0 == bx::strCmp(typen, "mediump", 7) || 0 == bx::strCmp(typen, "highp", 5)) { precision = typen; typen = nextWord(parse); } - if (0 == bx::strCmp(typen, "flat", 4) - || 0 == bx::strCmp(typen, "smooth", 6) - || 0 == bx::strCmp(typen, "noperspective", 13) - || 0 == bx::strCmp(typen, "centroid", 8) ) + if (0 == bx::strCmp(typen, "flat", 4) || 0 == bx::strCmp(typen, "smooth", 6) || 0 == bx::strCmp(typen, "noperspective", 13) || 0 == bx::strCmp(typen, "centroid", 8)) { - if ('f' == _options.shaderType - || profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if ('f' == _options.shaderType || profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { interpolation = typen; usesInterpolationQualifiers = true; @@ -1359,58 +1280,54 @@ namespace bgfx typen = nextWord(parse); } - bx::StringView name = nextWord(parse); + bx::StringView name = nextWord(parse); bx::StringView column = bx::strSubstr(parse, 0, 1); bx::StringView semantics; - if (0 == bx::strCmp(column, ":", 1) ) + if (0 == bx::strCmp(column, ":", 1)) { - parse = bx::strLTrimSpace(bx::StringView(parse.getPtr() + 1, parse.getTerm() ) ); + parse = bx::strLTrimSpace(bx::StringView(parse.getPtr() + 1, parse.getTerm())); semantics = nextWord(parse); } bx::StringView assign = bx::strSubstr(parse, 0, 1); bx::StringView init; - if (0 == bx::strCmp(assign, "=", 1) ) + if (0 == bx::strCmp(assign, "=", 1)) { - parse = bx::strLTrimSpace(bx::StringView(parse.getPtr() + 1, parse.getTerm() ) ); - init.set(parse.getPtr(), eol.getPtr() ); + parse = bx::strLTrimSpace(bx::StringView(parse.getPtr() + 1, parse.getTerm())); + init.set(parse.getPtr(), eol.getPtr()); } - if (!typen.isEmpty() - && !name.isEmpty() - && !semantics.isEmpty() ) + if (!typen.isEmpty() && !name.isEmpty() && !semantics.isEmpty()) { Varying var; - if (!precision.isEmpty() ) + if (!precision.isEmpty()) { - var.m_precision.assign(precision.getPtr(), precision.getTerm() ); + var.m_precision.assign(precision.getPtr(), precision.getTerm()); } - if (!interpolation.isEmpty() ) + if (!interpolation.isEmpty()) { - var.m_interpolation.assign(interpolation.getPtr(), interpolation.getTerm() ); + var.m_interpolation.assign(interpolation.getPtr(), interpolation.getTerm()); } - var.m_type.assign(typen.getPtr(), typen.getTerm() ); - var.m_name.assign(name.getPtr(), name.getTerm() ); - var.m_semantics.assign(semantics.getPtr(), semantics.getTerm() ); + var.m_type.assign(typen.getPtr(), typen.getTerm()); + var.m_name.assign(name.getPtr(), name.getTerm()); + var.m_semantics.assign(semantics.getPtr(), semantics.getTerm()); - if (profile->lang == ShadingLang::HLSL - && profile->id < 400 - && var.m_semantics == "BITANGENT") + if (profile->lang == ShadingLang::HLSL && profile->id < 400 && var.m_semantics == "BITANGENT") { var.m_semantics = "BINORMAL"; } - if (!init.isEmpty() ) + if (!init.isEmpty()) { - var.m_init.assign(init.getPtr(), init.getTerm() ); + var.m_init.assign(init.getPtr(), init.getTerm()); } - varyingMap.insert(std::make_pair(var.m_name, var) ); + varyingMap.insert(std::make_pair(var.m_name, var)); } - parse = bx::strLTrimSpace(bx::strFindNl(bx::StringView(eol.getPtr(), term.getTerm() ) ) ); + parse = bx::strLTrimSpace(bx::strFindNl(bx::StringView(eol.getPtr(), term.getTerm()))); } } @@ -1422,8 +1339,8 @@ namespace bgfx uint32_t outputHash = 0; bx::ErrorAssert err; - char* data; - char* input; + char *data; + char *input; { data = _shader; uint32_t size = _shaderLen; @@ -1436,7 +1353,7 @@ namespace bgfx // first preprocess pass is used to strip all comments before // substituting code. bool ok = preprocessor.run(data); - delete [] data; + delete[] data; if (!ok) { @@ -1444,42 +1361,42 @@ namespace bgfx } size = (uint32_t)preprocessor.m_preprocessed.size(); - data = new char[size+padding+1]; + data = new char[size + padding + 1]; bx::memCopy(data, preprocessor.m_preprocessed.c_str(), size); - bx::memSet(&data[size], 0, padding+1); + bx::memSet(&data[size], 0, padding + 1); } strNormalizeEol(data); - input = const_cast(bx::strLTrimSpace(data).getPtr() ); + input = const_cast(bx::strLTrimSpace(data).getPtr()); while (input[0] == '$') { - bx::StringView str = bx::strLTrimSpace(input+1); + bx::StringView str = bx::strLTrimSpace(input + 1); bx::StringView eol = bx::strFindEol(str); - bx::StringView nl = bx::strFindNl(eol); - input = const_cast(nl.getPtr() ); + bx::StringView nl = bx::strFindNl(eol); + input = const_cast(nl.getPtr()); - if (0 == bx::strCmp(str, "input", 5) ) + if (0 == bx::strCmp(str, "input", 5)) { - str = bx::StringView(str.getPtr() + 5, str.getTerm() ); + str = bx::StringView(str.getPtr() + 5, str.getTerm()); bx::StringView comment = bx::strFind(str, "//"); eol = !comment.isEmpty() && comment.getPtr() < eol.getPtr() ? comment.getPtr() : eol; - inputHash = parseInOut(shaderInputs, bx::StringView(str.getPtr(), eol.getPtr() ) ); + inputHash = parseInOut(shaderInputs, bx::StringView(str.getPtr(), eol.getPtr())); } - else if (0 == bx::strCmp(str, "output", 6) ) + else if (0 == bx::strCmp(str, "output", 6)) { - str = bx::StringView(str.getPtr() + 6, str.getTerm() ); + str = bx::StringView(str.getPtr() + 6, str.getTerm()); bx::StringView comment = bx::strFind(str, "//"); eol = !comment.isEmpty() && comment.getPtr() < eol.getPtr() ? comment.getPtr() : eol; - outputHash = parseInOut(shaderOutputs, bx::StringView(str.getPtr(), eol.getPtr() ) ); + outputHash = parseInOut(shaderOutputs, bx::StringView(str.getPtr(), eol.getPtr())); } - else if (0 == bx::strCmp(str, "raw", 3) ) + else if (0 == bx::strCmp(str, "raw", 3)) { raw = true; - str = bx::StringView(str.getPtr() + 3, str.getTerm() ); + str = bx::StringView(str.getPtr() + 3, str.getTerm()); } - input = const_cast(bx::strLTrimSpace(input).getPtr() ); + input = const_cast(bx::strLTrimSpace(input).getPtr()); } } @@ -1488,18 +1405,18 @@ namespace bgfx { for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it) { - if (bx::findIdentifierMatch(it->c_str(), s_allowedVertexShaderInputs).isEmpty() ) + if (bx::findIdentifierMatch(it->c_str(), s_allowedVertexShaderInputs).isEmpty()) { invalidShaderAttribute = true; bx::write(_messageWriter, &messageErr, - "Invalid vertex shader input attribute '%s'.\n" - "\n" - "Valid input attributes:\n" - " a_position, a_normal, a_tangent, a_bitangent, a_color0, a_color1, a_color2, a_color3, a_indices, a_weight,\n" - " a_texcoord0, a_texcoord1, a_texcoord2, a_texcoord3, a_texcoord4, a_texcoord5, a_texcoord6, a_texcoord7,\n" - " i_data0, i_data1, i_data2, i_data3, i_data4.\n" - "\n" - , it->c_str() ); + "Invalid vertex shader input attribute '%s'.\n" + "\n" + "Valid input attributes:\n" + " a_position, a_normal, a_tangent, a_bitangent, a_color0, a_color1, a_color2, a_color3, a_indices, a_weight,\n" + " a_texcoord0, a_texcoord1, a_texcoord2, a_texcoord3, a_texcoord4, a_texcoord5, a_texcoord6, a_texcoord7,\n" + " i_data0, i_data1, i_data2, i_data3, i_data4.\n" + "\n", + it->c_str()); break; } } @@ -1560,21 +1477,20 @@ namespace bgfx else if ('c' == _options.shaderType) // Compute { bx::StringView entry = bx::strFind(input, "void main()"); - if (entry.isEmpty() ) + if (entry.isEmpty()) { bx::write(_messageWriter, &messageErr, "Shader entry point 'void main()' is not found.\n"); } else { - if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { } else { if (profile->lang == ShadingLang::PSSL) { - preprocessor.writef(getPsslPreamble() ); + preprocessor.writef(getPsslPreamble()); } preprocessor.writef( @@ -1592,68 +1508,54 @@ namespace bgfx "#define vec4 float4\n" "#define mat2 float2x2\n" "#define mat3 float3x3\n" - "#define mat4 float4x4\n" - ); + "#define mat4 float4x4\n"); - *const_cast(entry.getPtr() + 4) = '_'; + *const_cast(entry.getPtr() + 4) = '_'; preprocessor.writef("#define void_main()"); preprocessor.writef(" \\\n\tvoid main("); uint32_t arg = 0; - const bool hasLocalInvocationID = !bx::strFind(input, "gl_LocalInvocationID").isEmpty(); + const bool hasLocalInvocationID = !bx::strFind(input, "gl_LocalInvocationID").isEmpty(); const bool hasLocalInvocationIndex = !bx::strFind(input, "gl_LocalInvocationIndex").isEmpty(); - const bool hasGlobalInvocationID = !bx::strFind(input, "gl_GlobalInvocationID").isEmpty(); - const bool hasWorkGroupID = !bx::strFind(input, "gl_WorkGroupID").isEmpty(); + const bool hasGlobalInvocationID = !bx::strFind(input, "gl_GlobalInvocationID").isEmpty(); + const bool hasWorkGroupID = !bx::strFind(input, "gl_WorkGroupID").isEmpty(); if (hasLocalInvocationID) { preprocessor.writef( - " \\\n\t%sint3 gl_LocalInvocationID : SV_GroupThreadID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sint3 gl_LocalInvocationID : SV_GroupThreadID", arg++ > 0 ? ", " : " "); } if (hasLocalInvocationIndex) { preprocessor.writef( - " \\\n\t%sint gl_LocalInvocationIndex : SV_GroupIndex" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sint gl_LocalInvocationIndex : SV_GroupIndex", arg++ > 0 ? ", " : " "); } if (hasGlobalInvocationID) { preprocessor.writef( - " \\\n\t%sint3 gl_GlobalInvocationID : SV_DispatchThreadID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sint3 gl_GlobalInvocationID : SV_DispatchThreadID", arg++ > 0 ? ", " : " "); } if (hasWorkGroupID) { preprocessor.writef( - " \\\n\t%sint3 gl_WorkGroupID : SV_GroupID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sint3 gl_WorkGroupID : SV_GroupID", arg++ > 0 ? ", " : " "); } preprocessor.writef( - " \\\n\t)\n" - ); + " \\\n\t)\n"); } - if (preprocessor.run(input) ) + if (preprocessor.run(input)) { if (_options.preprocessOnly) { bx::write( - _shaderWriter - , preprocessor.m_preprocessed.c_str() - , (int32_t)preprocessor.m_preprocessed.size() - , &err - ); + _shaderWriter, preprocessor.m_preprocessed.c_str(), (int32_t)preprocessor.m_preprocessed.size(), &err); return true; } @@ -1665,8 +1567,7 @@ namespace bgfx bx::write(_shaderWriter, uint32_t(0), &err); bx::write(_shaderWriter, outputHash, &err); - if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { if (profile->lang == ShadingLang::ESSL) { @@ -1675,10 +1576,7 @@ namespace bgfx else { bx::stringPrintf( - code - , "#version %d\n" - , (profile->lang != ShadingLang::GLSL) ? 430 : profile->id - ); + code, "#version %d\n", (profile->lang != ShadingLang::GLSL) ? 430 : profile->id); } code += preprocessor.m_preprocessed; @@ -1723,9 +1621,9 @@ namespace bgfx std::string ofp = _options.outputFilePath; ofp += ".d"; bx::FileWriter writer; - if (bx::open(&writer, ofp.c_str() ) ) + if (bx::open(&writer, ofp.c_str())) { - writef(&writer, "%s : %s\n", _options.outputFilePath.c_str(), preprocessor.m_depends.c_str() ); + writef(&writer, "%s : %s\n", _options.outputFilePath.c_str(), preprocessor.m_depends.c_str()); bx::close(&writer); } } @@ -1737,14 +1635,13 @@ namespace bgfx { bx::StringView shader(input); bx::StringView entry = bx::strFind(shader, "void main()"); - if (entry.isEmpty() ) + if (entry.isEmpty()) { bx::write(_messageWriter, &messageErr, "Shader entry point 'void main()' is not found.\n"); } else { - if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { if (profile->lang != ShadingLang::ESSL) { @@ -1752,15 +1649,13 @@ namespace bgfx // not as GLSL language 1.2 specs shadow2D/Proj. preprocessor.writef( "#define shadow2D(_sampler, _coord) bgfxShadow2D(_sampler, _coord).x\n" - "#define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord).x\n" - ); + "#define shadow2DProj(_sampler, _coord) bgfxShadow2DProj(_sampler, _coord).x\n"); } // gl_FragColor and gl_FragData are deprecated for essl > 300 - if (profile->lang == ShadingLang::ESSL - && profile->id >= 300) + if (profile->lang == ShadingLang::ESSL && profile->id >= 300) { - const bool hasFragColor = !bx::strFind(input, "gl_FragColor").isEmpty(); + const bool hasFragColor = !bx::strFind(input, "gl_FragColor").isEmpty(); bool hasFragData[8] = {}; uint32_t numFragData = 0; for (uint32_t ii = 0; ii < BX_COUNTOF(hasFragData); ++ii) @@ -1785,31 +1680,20 @@ namespace bgfx for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; - const char* name = var.m_name.c_str(); + const Varying &var = varyingIt->second; + const char *name = var.m_name.c_str(); - if (0 == bx::strCmp(name, "a_", 2) - || 0 == bx::strCmp(name, "i_", 2) ) + if (0 == bx::strCmp(name, "a_", 2) || 0 == bx::strCmp(name, "i_", 2)) { preprocessor.writef( - "attribute %s %s %s %s;\n" - , var.m_precision.c_str() - , var.m_interpolation.c_str() - , var.m_type.c_str() - , name - ); + "attribute %s %s %s %s;\n", var.m_precision.c_str(), var.m_interpolation.c_str(), var.m_type.c_str(), name); } else { preprocessor.writef( - "%s varying %s %s %s;\n" - , var.m_interpolation.c_str() - , var.m_precision.c_str() - , var.m_type.c_str() - , name - ); + "%s varying %s %s %s;\n", var.m_interpolation.c_str(), var.m_precision.c_str(), var.m_type.c_str(), name); } } } @@ -1817,14 +1701,10 @@ namespace bgfx for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; - preprocessor.writef("%s varying %s %s;\n" - , var.m_interpolation.c_str() - , var.m_type.c_str() - , var.m_name.c_str() - ); + const Varying &var = varyingIt->second; + preprocessor.writef("%s varying %s %s;\n", var.m_interpolation.c_str(), var.m_type.c_str(), var.m_name.c_str()); } } } @@ -1832,7 +1712,7 @@ namespace bgfx { if (profile->lang == ShadingLang::PSSL) { - preprocessor.writef(getPsslPreamble() ); + preprocessor.writef(getPsslPreamble()); } preprocessor.writef( @@ -1850,33 +1730,30 @@ namespace bgfx "#define vec4 float4\n" "#define mat2 float2x2\n" "#define mat3 float3x3\n" - "#define mat4 float4x4\n" - ); + "#define mat4 float4x4\n"); - if (profile->lang == ShadingLang::HLSL - && profile->id < 400) + if (profile->lang == ShadingLang::HLSL && profile->id < 400) { preprocessor.writef( "#define centroid\n" "#define flat\n" "#define noperspective\n" - "#define smooth\n" - ); + "#define smooth\n"); } - *const_cast(entry.getPtr() + 4) = '_'; + *const_cast(entry.getPtr() + 4) = '_'; if ('f' == _options.shaderType) { - bx::StringView insert = bx::strFind(bx::StringView(entry.getPtr(), shader.getTerm() ), "{"); - if (!insert.isEmpty() ) + bx::StringView insert = bx::strFind(bx::StringView(entry.getPtr(), shader.getTerm()), "{"); + if (!insert.isEmpty()) { - insert = strInsert(const_cast(insert.getPtr()+1), "\nvec4 bgfx_VoidFrag = vec4_splat(0.0);\n"); + insert = strInsert(const_cast(insert.getPtr() + 1), "\nvec4 bgfx_VoidFrag = vec4_splat(0.0);\n"); } - const bool hasFragColor = !bx::strFind(input, "gl_FragColor").isEmpty(); - const bool hasFragCoord = !bx::strFind(input, "gl_FragCoord").isEmpty() || profile->id >= 400; - const bool hasFragDepth = !bx::strFind(input, "gl_FragDepth").isEmpty(); + const bool hasFragColor = !bx::strFind(input, "gl_FragColor").isEmpty(); + const bool hasFragCoord = !bx::strFind(input, "gl_FragCoord").isEmpty() || profile->id >= 400; + const bool hasFragDepth = !bx::strFind(input, "gl_FragDepth").isEmpty(); const bool hasFrontFacing = !bx::strFind(input, "gl_FrontFacing").isEmpty(); const bool hasPrimitiveId = !bx::strFind(input, "gl_PrimitiveID").isEmpty() && BGFX_CAPS_PRIMITIVE_ID; @@ -1906,11 +1783,9 @@ namespace bgfx // targets. hasFragData[0] |= hasFragColor || profile->id < 400; - if (!insert.isEmpty() - && profile->id < 400 - && !hasFragColor) + if (!insert.isEmpty() && profile->id < 400 && !hasFragColor) { - insert = strInsert(const_cast(insert.getPtr()+1), "\ngl_FragColor = bgfx_VoidFrag;\n"); + insert = strInsert(const_cast(insert.getPtr() + 1), "\ngl_FragColor = bgfx_VoidFrag;\n"); } } @@ -1928,16 +1803,10 @@ namespace bgfx for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; - preprocessor.writef(" \\\n\t%s%s %s %s : %s" - , arg++ > 0 ? ", " : " " - , interpolationDx11(var.m_interpolation.c_str() ) - , var.m_type.c_str() - , var.m_name.c_str() - , var.m_semantics.c_str() - ); + const Varying &var = varyingIt->second; + preprocessor.writef(" \\\n\t%s%s %s %s : %s", arg++ > 0 ? ", " : " ", interpolationDx11(var.m_interpolation.c_str()), var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str()); } } @@ -1961,9 +1830,7 @@ namespace bgfx if (hasFragDepth) { preprocessor.writef( - " \\\n\t%sout float gl_FragDepth : SV_DEPTH" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sout float gl_FragDepth : SV_DEPTH", arg++ > 0 ? ", " : " "); } if (hasFrontFacing) @@ -1971,16 +1838,12 @@ namespace bgfx if (profile->id < 400) { preprocessor.writef( - " \\\n\t%sfloat __vface : VFACE" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sfloat __vface : VFACE", arg++ > 0 ? ", " : " "); } else { preprocessor.writef( - " \\\n\t%sbool gl_FrontFacing : SV_IsFrontFace" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%sbool gl_FrontFacing : SV_IsFrontFace", arg++ > 0 ? ", " : " "); } } @@ -1989,9 +1852,7 @@ namespace bgfx if (profile->id >= 400) { preprocessor.writef( - " \\\n\t%suint gl_PrimitiveID : SV_PrimitiveID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%suint gl_PrimitiveID : SV_PrimitiveID", arg++ > 0 ? ", " : " "); } else { @@ -2001,33 +1862,31 @@ namespace bgfx } preprocessor.writef( - " \\\n\t)\n" - ); + " \\\n\t)\n"); if (hasFrontFacing) { if (profile->id < 400) { preprocessor.writef( - "#define gl_FrontFacing (__vface >= 0.0)\n" - ); + "#define gl_FrontFacing (__vface >= 0.0)\n"); } } } else if ('v' == _options.shaderType) { - const bool hasVertexId = !bx::strFind(input, "gl_VertexID").isEmpty(); + const bool hasVertexId = !bx::strFind(input, "gl_VertexID").isEmpty(); const bool hasInstanceId = !bx::strFind(input, "gl_InstanceID").isEmpty(); const bool hasViewportId = !bx::strFind(input, "gl_ViewportIndex").isEmpty(); - const bool hasLayerId = !bx::strFind(input, "gl_Layer").isEmpty(); + const bool hasLayerId = !bx::strFind(input, "gl_Layer").isEmpty(); - bx::StringView brace = bx::strFind(bx::StringView(entry.getPtr(), shader.getTerm() ), "{"); - if (!brace.isEmpty() ) + bx::StringView brace = bx::strFind(bx::StringView(entry.getPtr(), shader.getTerm()), "{"); + if (!brace.isEmpty()) { - bx::StringView block = bx::strFindBlock(bx::StringView(brace.getPtr(), shader.getTerm() ), '{', '}'); - if (!block.isEmpty() ) + bx::StringView block = bx::strFindBlock(bx::StringView(brace.getPtr(), shader.getTerm()), '{', '}'); + if (!block.isEmpty()) { - strInsert(const_cast(block.getTerm()-1), "__RETURN__;\n"); + strInsert(const_cast(block.getTerm() - 1), "__RETURN__;\n"); } } @@ -2035,27 +1894,18 @@ namespace bgfx "struct Output\n" "{\n" "\tvec4 gl_Position : SV_POSITION;\n" - "#define gl_Position _varying_.gl_Position\n" - ); + "#define gl_Position _varying_.gl_Position\n"); for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; + const Varying &var = varyingIt->second; preprocessor.writef( - "\t%s %s %s : %s;\n" - , interpolationDx11(var.m_interpolation.c_str() ) - , var.m_type.c_str() - , var.m_name.c_str() - , var.m_semantics.c_str() - ); + "\t%s %s %s : %s;\n", interpolationDx11(var.m_interpolation.c_str()), var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str()); preprocessor.writef( - "#define %s _varying_.%s\n" - , var.m_name.c_str() - , var.m_name.c_str() - ); + "#define %s _varying_.%s\n", var.m_name.c_str(), var.m_name.c_str()); } } @@ -2065,8 +1915,7 @@ namespace bgfx { preprocessor.writef( "\tuint gl_ViewportIndex : SV_ViewportArrayIndex;\n" - "#define gl_ViewportIndex _varying_.gl_ViewportIndex\n" - ); + "#define gl_ViewportIndex _varying_.gl_ViewportIndex\n"); } else { @@ -2081,8 +1930,7 @@ namespace bgfx { preprocessor.writef( "\tuint gl_Layer : SV_RenderTargetArrayIndex;\n" - "#define gl_Layer _varying_.gl_Layer\n" - ); + "#define gl_Layer _varying_.gl_Layer\n"); } else { @@ -2092,8 +1940,7 @@ namespace bgfx } preprocessor.writef( - "};\n" - ); + "};\n"); preprocessor.writef("#define void_main() \\\n"); preprocessor.writef("Output main("); @@ -2101,16 +1948,11 @@ namespace bgfx for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; + const Varying &var = varyingIt->second; preprocessor.writef( - " \\\n\t%s%s %s : %s" - , arg++ > 0 ? ", " : "" - , var.m_type.c_str() - , var.m_name.c_str() - , var.m_semantics.c_str() - ); + " \\\n\t%s%s %s : %s", arg++ > 0 ? ", " : "", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str()); } } @@ -2119,9 +1961,7 @@ namespace bgfx if (profile->id >= 400) { preprocessor.writef( - " \\\n\t%suint gl_VertexID : SV_VertexID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%suint gl_VertexID : SV_VertexID", arg++ > 0 ? ", " : " "); } else { @@ -2135,9 +1975,7 @@ namespace bgfx if (profile->id >= 400) { preprocessor.writef( - " \\\n\t%suint gl_InstanceID : SV_InstanceID" - , arg++ > 0 ? ", " : " " - ); + " \\\n\t%suint gl_InstanceID : SV_InstanceID", arg++ > 0 ? ", " : " "); } else { @@ -2149,19 +1987,18 @@ namespace bgfx preprocessor.writef( ") \\\n" "{ \\\n" - "\tOutput _varying_;" - ); + "\tOutput _varying_;"); for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it) { VaryingMap::const_iterator varyingIt = varyingMap.find(*it); - if (varyingIt != varyingMap.end() ) + if (varyingIt != varyingMap.end()) { - const Varying& var = varyingIt->second; - preprocessor.writef(" \\\n\t%s", var.m_name.c_str() ); - if (!var.m_init.empty() ) + const Varying &var = varyingIt->second; + preprocessor.writef(" \\\n\t%s", var.m_name.c_str()); + if (!var.m_init.empty()) { - preprocessor.writef(" = %s", var.m_init.c_str() ); + preprocessor.writef(" = %s", var.m_init.c_str()); } preprocessor.writef(";"); } @@ -2169,25 +2006,19 @@ namespace bgfx preprocessor.writef( "\n#define __RETURN__ \\\n" - "\t} \\\n" - ); + "\t} \\\n"); preprocessor.writef( - "\treturn _varying_" - ); + "\treturn _varying_"); } } - if (preprocessor.run(input) ) + if (preprocessor.run(input)) { if (_options.preprocessOnly) { bx::write( - _shaderWriter - , preprocessor.m_preprocessed.c_str() - , (int32_t)preprocessor.m_preprocessed.size() - , &err - ); + _shaderWriter, preprocessor.m_preprocessed.c_str(), (int32_t)preprocessor.m_preprocessed.size(), &err); return true; } @@ -2214,23 +2045,16 @@ namespace bgfx bx::write(_shaderWriter, outputHash, &err); } - if (profile->lang == ShadingLang::GLSL - || profile->lang == ShadingLang::ESSL) + if (profile->lang == ShadingLang::GLSL || profile->lang == ShadingLang::ESSL) { - const bx::StringView preprocessedInput(preprocessor.m_preprocessed.c_str() ); + const bx::StringView preprocessedInput(preprocessor.m_preprocessed.c_str()); uint32_t glsl_profile = profile->id; - const bool usesBitsToEncoders = true - && _options.shaderType == 'f' - && !bx::findIdentifierMatch(preprocessedInput, s_bitsToEncoders).isEmpty() - ; + const bool usesBitsToEncoders = true && _options.shaderType == 'f' && !bx::findIdentifierMatch(preprocessedInput, s_bitsToEncoders).isEmpty(); - if (!bx::strFind(preprocessedInput, "layout(std430").isEmpty() - || !bx::strFind(preprocessedInput, "image2D").isEmpty() - || usesBitsToEncoders) + if (!bx::strFind(preprocessedInput, "layout(std430").isEmpty() || !bx::strFind(preprocessedInput, "image2D").isEmpty() || usesBitsToEncoders) { - if (profile->lang == ShadingLang::GLSL - && glsl_profile < 430) + if (profile->lang == ShadingLang::GLSL && glsl_profile < 430) { glsl_profile = 430; } @@ -2242,76 +2066,53 @@ namespace bgfx if (glsl_profile < 400) { - const bool usesTextureLod = false - || !bx::findIdentifierMatch(input, s_ARB_shader_texture_lod).isEmpty() - || !bx::findIdentifierMatch(input, s_EXT_shader_texture_lod).isEmpty() - ; - - const bool usesGpuShader5 = true - && _options.shaderType != 'f' - && !bx::findIdentifierMatch(input, s_ARB_gpu_shader5).isEmpty() - ; - - const bool usesInstanceID = !bx::findIdentifierMatch(input, "gl_InstanceID").isEmpty(); - const bool usesGpuShader4 = !bx::findIdentifierMatch(input, s_EXT_gpu_shader4).isEmpty(); - const bool usesTexelFetch = !bx::findIdentifierMatch(input, s_texelFetch).isEmpty(); - const bool usesTextureMS = !bx::findIdentifierMatch(input, s_ARB_texture_multisample).isEmpty(); - const bool usesTextureArray = !bx::findIdentifierMatch(input, s_textureArray).isEmpty(); - const bool usesPacking = !bx::findIdentifierMatch(input, s_ARB_shading_language_packing).isEmpty(); + const bool usesTextureLod = false || !bx::findIdentifierMatch(input, s_ARB_shader_texture_lod).isEmpty() || !bx::findIdentifierMatch(input, s_EXT_shader_texture_lod).isEmpty(); + + const bool usesGpuShader5 = true && _options.shaderType != 'f' && !bx::findIdentifierMatch(input, s_ARB_gpu_shader5).isEmpty(); + + const bool usesInstanceID = !bx::findIdentifierMatch(input, "gl_InstanceID").isEmpty(); + const bool usesGpuShader4 = !bx::findIdentifierMatch(input, s_EXT_gpu_shader4).isEmpty(); + const bool usesTexelFetch = !bx::findIdentifierMatch(input, s_texelFetch).isEmpty(); + const bool usesTextureMS = !bx::findIdentifierMatch(input, s_ARB_texture_multisample).isEmpty(); + const bool usesTextureArray = !bx::findIdentifierMatch(input, s_textureArray).isEmpty(); + const bool usesPacking = !bx::findIdentifierMatch(input, s_ARB_shading_language_packing).isEmpty(); const bool usesViewportLayerArray = !bx::findIdentifierMatch(input, s_ARB_shader_viewport_layer_array).isEmpty(); - const bool usesUnsignedVecs = !bx::findIdentifierMatch(preprocessedInput, s_unsignedVecs).isEmpty(); + const bool usesIntegerVecs = !bx::findIdentifierMatch(preprocessedInput, s_integerVecs).isEmpty(); if (profile->lang != ShadingLang::ESSL) { - const bool need130 = (120 == glsl_profile && (false - || !bx::findIdentifierMatch(input, s_130).isEmpty() - || usesInterpolationQualifiers - || usesTexelFetch - || usesUnsignedVecs - ) ); + const bool need130 = (120 == glsl_profile && (false || !bx::findIdentifierMatch(input, s_130).isEmpty() || usesInterpolationQualifiers || usesTexelFetch || usesIntegerVecs)); bx::stringPrintf(code, "#version %d\n", need130 ? 130 : glsl_profile); if (need130) { - bx::stringPrintf(code, "#define varying %s\n" - , 'f' == _options.shaderType ? "in" : "out" - ); + bx::stringPrintf(code, "#define varying %s\n", 'f' == _options.shaderType ? "in" : "out"); } if (usesInstanceID) { - bx::stringPrintf(code - , "#extension GL_ARB_draw_instanced : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_draw_instanced : enable\n"); } if (usesViewportLayerArray) { - bx::stringPrintf(code - , "#extension GL_ARB_shader_viewport_layer_array : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_shader_viewport_layer_array : enable\n"); } if (usesGpuShader4) { - bx::stringPrintf(code - , "#extension GL_EXT_gpu_shader4 : enable\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_gpu_shader4 : enable\n"); } if (usesGpuShader5) { - bx::stringPrintf(code - , "#extension GL_ARB_gpu_shader5 : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_gpu_shader5 : enable\n"); } if (usesPacking) { - bx::stringPrintf(code - , "#extension GL_ARB_shading_language_packing : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_shading_language_packing : enable\n"); } bool ARB_shader_texture_lod = false; @@ -2322,80 +2123,56 @@ namespace bgfx if ('f' == _options.shaderType) { ARB_shader_texture_lod = true; - bx::stringPrintf(code - , "#extension GL_ARB_shader_texture_lod : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_shader_texture_lod : enable\n"); } else { EXT_shader_texture_lod = true; - bx::stringPrintf(code - , "#extension GL_EXT_shader_texture_lod : enable\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_shader_texture_lod : enable\n"); } } if (usesTextureMS) { - bx::stringPrintf(code - , "#extension GL_ARB_texture_multisample : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_texture_multisample : enable\n"); } if (usesTextureArray) { - bx::stringPrintf(code - , "#extension GL_EXT_texture_array : enable\n" - ); - } - - if (130 > glsl_profile) - { - bx::stringPrintf(code, - "#define ivec2 vec2\n" - "#define ivec3 vec3\n" - "#define ivec4 vec4\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_texture_array : enable\n"); } if (ARB_shader_texture_lod) { bx::stringPrintf(code, - "#define texture2DProjLod texture2DProjLodARB\n" - "#define texture2DGrad texture2DGradARB\n" - "#define texture2DProjGrad texture2DProjGradARB\n" - "#define textureCubeGrad textureCubeGradARB\n" - ); + "#define texture2DProjLod texture2DProjLodARB\n" + "#define texture2DGrad texture2DGradARB\n" + "#define texture2DProjGrad texture2DProjGradARB\n" + "#define textureCubeGrad textureCubeGradARB\n"); } else if (EXT_shader_texture_lod) { bx::stringPrintf(code, - "#define texture2DProjLod texture2DProjLodEXT\n" - "#define texture2DGrad texture2DGradEXT\n" - "#define texture2DProjGrad texture2DProjGradEXT\n" - "#define textureCubeGrad textureCubeGradEXT\n" - ); + "#define texture2DProjLod texture2DProjLodEXT\n" + "#define texture2DGrad texture2DGradEXT\n" + "#define texture2DProjGrad texture2DProjGradEXT\n" + "#define textureCubeGrad textureCubeGradEXT\n"); } - if (need130 || (glsl_profile >= 130) ) + if (need130 || (glsl_profile >= 130)) { - bx::stringPrintf(code - , "#define bgfxShadow2D(_sampler, _coord) vec4_splat(texture(_sampler, _coord) )\n" - "#define bgfxShadow2DProj(_sampler, _coord) vec4_splat(textureProj(_sampler, _coord) )\n" - ); + bx::stringPrintf(code, "#define bgfxShadow2D(_sampler, _coord) vec4_splat(texture(_sampler, _coord) )\n" + "#define bgfxShadow2DProj(_sampler, _coord) vec4_splat(textureProj(_sampler, _coord) )\n"); } else { - bx::stringPrintf(code - , "#define bgfxShadow2D shadow2D\n" - "#define bgfxShadow2DProj shader2DProj\n" - ); + bx::stringPrintf(code, "#define bgfxShadow2D shadow2D\n" + "#define bgfxShadow2DProj shader2DProj\n"); } } else { - if (glsl_profile < 300 - && usesUnsignedVecs) + if (glsl_profile < 300 && usesIntegerVecs) { glsl_profile = 300; } @@ -2404,9 +2181,7 @@ namespace bgfx { bx::stringPrintf(code, "#version %d es\n", glsl_profile); bx::stringPrintf(code, "#define attribute in\n"); - bx::stringPrintf(code, "#define varying %s\n" - , 'f' == _options.shaderType ? "in" : "out" - ); + bx::stringPrintf(code, "#define varying %s\n", 'f' == _options.shaderType ? "in" : "out"); bx::stringPrintf(code, "precision highp float;\n"); bx::stringPrintf(code, "precision highp int;\n"); } @@ -2420,72 +2195,56 @@ namespace bgfx // This will be stripped later. if (usesTextureLod) { - bx::stringPrintf(code - , "#extension GL_EXT_shader_texture_lod : enable\n" - "#define texture2DLod texture2DLodEXT\n" - "#define texture2DGrad texture2DGradEXT\n" - "#define texture2DProjLod texture2DProjLodEXT\n" - "#define texture2DProjGrad texture2DProjGradEXT\n" - "#define textureCubeLod textureCubeLodEXT\n" - "#define textureCubeGrad textureCubeGradEXT\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_shader_texture_lod : enable\n" + "#define texture2DLod texture2DLodEXT\n" + "#define texture2DGrad texture2DGradEXT\n" + "#define texture2DProjLod texture2DProjLodEXT\n" + "#define texture2DProjGrad texture2DProjGradEXT\n" + "#define textureCubeLod textureCubeLodEXT\n" + "#define textureCubeGrad textureCubeGradEXT\n"); } - if (!bx::findIdentifierMatch(input, s_OES_standard_derivatives).isEmpty() ) + if (!bx::findIdentifierMatch(input, s_OES_standard_derivatives).isEmpty()) { bx::stringPrintf(code, "#extension GL_OES_standard_derivatives : enable\n"); } - if (!bx::findIdentifierMatch(input, s_OES_texture_3D).isEmpty() ) + if (!bx::findIdentifierMatch(input, s_OES_texture_3D).isEmpty()) { bx::stringPrintf(code, "#extension GL_OES_texture_3D : enable\n"); } - if (glsl_profile < 300 - && !bx::findIdentifierMatch(input, s_EXT_shadow_samplers).isEmpty() ) + if (glsl_profile < 300 && !bx::findIdentifierMatch(input, s_EXT_shadow_samplers).isEmpty()) { - bx::stringPrintf(code - , "#extension GL_EXT_shadow_samplers : enable\n" - "#define shadow2D shadow2DEXT\n" - "#define shadow2DProj shadow2DProjEXT\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_shadow_samplers : enable\n" + "#define shadow2D shadow2DEXT\n" + "#define shadow2DProj shadow2DProjEXT\n"); } else { - bx::stringPrintf(code - , "#define shadow2D(_sampler, _coord) texture(_sampler, _coord)\n" - "#define shadow2DProj(_sampler, _coord) textureProj(_sampler, _coord)\n" - ); + bx::stringPrintf(code, "#define shadow2D(_sampler, _coord) texture(_sampler, _coord)\n" + "#define shadow2DProj(_sampler, _coord) textureProj(_sampler, _coord)\n"); } if (usesGpuShader5) { - bx::stringPrintf(code - , "#extension GL_ARB_gpu_shader5 : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_gpu_shader5 : enable\n"); } if (usesPacking) { - bx::stringPrintf(code - , "#extension GL_ARB_shading_language_packing : enable\n" - ); + bx::stringPrintf(code, "#extension GL_ARB_shading_language_packing : enable\n"); } - if (glsl_profile < 300 - && !bx::findIdentifierMatch(input, "gl_FragDepth").isEmpty() ) + if (glsl_profile < 300 && !bx::findIdentifierMatch(input, "gl_FragDepth").isEmpty()) { - bx::stringPrintf(code - , "#extension GL_EXT_frag_depth : enable\n" - "#define gl_FragDepth gl_FragDepthEXT\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_frag_depth : enable\n" + "#define gl_FragDepth gl_FragDepthEXT\n"); } if (usesTextureArray) { - bx::stringPrintf(code - , "#extension GL_EXT_texture_array : enable\n" - ); + bx::stringPrintf(code, "#extension GL_EXT_texture_array : enable\n"); } if (glsl_profile == 100) @@ -2528,8 +2287,7 @@ namespace bgfx " , vec4(v0.z, v1.z, v2.z, v3.z)\n" " , vec4(v0.w, v1.w, v2.w, v3.w)\n" " );\n" - "}\n" - ; + "}\n"; } } } @@ -2539,40 +2297,31 @@ namespace bgfx if (120 < glsl_profile) { - if (!bx::findIdentifierMatch(input, "gl_FragColor").isEmpty() ) + if (!bx::findIdentifierMatch(input, "gl_FragColor").isEmpty()) { - bx::stringPrintf(code - , "out vec4 bgfx_FragColor;\n" - "#define gl_FragColor bgfx_FragColor\n" - ); + bx::stringPrintf(code, "out vec4 bgfx_FragColor;\n" + "#define gl_FragColor bgfx_FragColor\n"); } } - bx::stringPrintf(code - , "#define texture2D texture\n" - "#define texture2DLod textureLod\n" - "#define texture2DGrad textureGrad\n" - "#define texture2DProjLod textureProjLod\n" - "#define texture2DProjGrad textureProjGrad\n" - "#define textureCubeLod textureLod\n" - "#define textureCubeGrad textureGrad\n" - "#define texture3D texture\n" - "#define texture2DLodOffset textureLodOffset\n" - ); + bx::stringPrintf(code, "#define texture2D texture\n" + "#define texture2DLod textureLod\n" + "#define texture2DGrad textureGrad\n" + "#define texture2DProjLod textureProjLod\n" + "#define texture2DProjGrad textureProjGrad\n" + "#define textureCubeLod textureLod\n" + "#define textureCubeGrad textureGrad\n" + "#define texture3D texture\n" + "#define texture2DLodOffset textureLodOffset\n"); bx::stringPrintf(code, "#define attribute in\n"); - bx::stringPrintf(code, "#define varying %s\n" - , 'f' == _options.shaderType ? "in" : "out" - ); - - bx::stringPrintf(code - , "#define bgfxShadow2D(_sampler, _coord) vec4_splat(texture(_sampler, _coord) )\n" - "#define bgfxShadow2DProj(_sampler, _coord) vec4_splat(textureProj(_sampler, _coord) )\n" - ); + bx::stringPrintf(code, "#define varying %s\n", 'f' == _options.shaderType ? "in" : "out"); + + bx::stringPrintf(code, "#define bgfxShadow2D(_sampler, _coord) vec4_splat(texture(_sampler, _coord) )\n" + "#define bgfxShadow2DProj(_sampler, _coord) vec4_splat(textureProj(_sampler, _coord) )\n"); } - if ( (profile->lang == ShadingLang::GLSL && glsl_profile > 400) - || (profile->lang == ShadingLang::ESSL && glsl_profile > 300) ) + if ((profile->lang == ShadingLang::GLSL && glsl_profile > 400) || (profile->lang == ShadingLang::ESSL && glsl_profile > 300)) { code += preprocessor.m_preprocessed; @@ -2628,9 +2377,9 @@ namespace bgfx { std::string ofp = _options.outputFilePath + ".d"; bx::FileWriter writer; - if (bx::open(&writer, ofp.c_str() ) ) + if (bx::open(&writer, ofp.c_str())) { - writef(&writer, "%s : %s\n", _options.outputFilePath.c_str(), preprocessor.m_depends.c_str() ); + writef(&writer, "%s : %s\n", _options.outputFilePath.c_str(), preprocessor.m_depends.c_str()); bx::close(&writer); } } @@ -2639,27 +2388,23 @@ namespace bgfx } } - delete [] data; + delete[] data; return compiled; } - int compileShader(int _argc, const char* _argv[]) + int compileShader(int _argc, const char *_argv[]) { bx::CommandLine cmdLine(_argc, _argv); - if (cmdLine.hasArg('v', "version") ) + if (cmdLine.hasArg('v', "version")) { bx::printf( - "shaderc, bgfx shader compiler tool, version %d.%d.%d.\n" - , BGFX_SHADERC_VERSION_MAJOR - , BGFX_SHADERC_VERSION_MINOR - , BGFX_API_VERSION - ); + "shaderc, bgfx shader compiler tool, version %d.%d.%d.\n", BGFX_SHADERC_VERSION_MAJOR, BGFX_SHADERC_VERSION_MINOR, BGFX_API_VERSION); return bx::kExitSuccess; } - if (cmdLine.hasArg('h', "help") ) + if (cmdLine.hasArg('h', "help")) { help(); return bx::kExitFailure; @@ -2667,7 +2412,7 @@ namespace bgfx g_verbose = cmdLine.hasArg("verbose"); - const char* filePath = cmdLine.findOption('f'); + const char *filePath = cmdLine.findOption('f'); if (NULL == filePath) { help("Shader file name must be specified."); @@ -2675,15 +2420,14 @@ namespace bgfx } bool consoleOut = cmdLine.hasArg("stdout"); - const char* outFilePath = cmdLine.findOption('o'); - if (NULL == outFilePath - && !consoleOut) + const char *outFilePath = cmdLine.findOption('o'); + if (NULL == outFilePath && !consoleOut) { help("Output file name must be specified or use \"--stdout\" to output to stdout."); return bx::kExitFailure; } - const char* type = cmdLine.findOption('\0', "type"); + const char *type = cmdLine.findOption('\0', "type"); if (NULL == type) { help("Must specify shader type."); @@ -2697,7 +2441,7 @@ namespace bgfx options.disasm = cmdLine.hasArg('\0', "disasm"); - const char* platform = cmdLine.findOption('\0', "platform"); + const char *platform = cmdLine.findOption('\0', "platform"); if (NULL == platform) { platform = ""; @@ -2707,25 +2451,25 @@ namespace bgfx options.raw = cmdLine.hasArg('\0', "raw"); - const char* profile = cmdLine.findOption('p', "profile"); + const char *profile = cmdLine.findOption('p', "profile"); - if ( NULL != profile) + if (NULL != profile) { options.profile = profile; } { - options.debugInformation = cmdLine.hasArg('\0', "debug"); - options.avoidFlowControl = cmdLine.hasArg('\0', "avoid-flow-control"); - options.noPreshader = cmdLine.hasArg('\0', "no-preshader"); - options.partialPrecision = cmdLine.hasArg('\0', "partial-precision"); - options.preferFlowControl = cmdLine.hasArg('\0', "prefer-flow-control"); + options.debugInformation = cmdLine.hasArg('\0', "debug"); + options.avoidFlowControl = cmdLine.hasArg('\0', "avoid-flow-control"); + options.noPreshader = cmdLine.hasArg('\0', "no-preshader"); + options.partialPrecision = cmdLine.hasArg('\0', "partial-precision"); + options.preferFlowControl = cmdLine.hasArg('\0', "prefer-flow-control"); options.backwardsCompatibility = cmdLine.hasArg('\0', "backwards-compatibility"); - options.warningsAreErrors = cmdLine.hasArg('\0', "Werror"); - options.keepIntermediate = cmdLine.hasArg('\0', "keep-intermediate"); + options.warningsAreErrors = cmdLine.hasArg('\0', "Werror"); + options.keepIntermediate = cmdLine.hasArg('\0', "keep-intermediate"); uint32_t optimization = 3; - if (cmdLine.hasArg(optimization, 'O') ) + if (cmdLine.hasArg(optimization, 'O')) { options.optimize = true; options.optimizationLevel = optimization; @@ -2733,9 +2477,9 @@ namespace bgfx } bx::StringView bin2c; - if (cmdLine.hasArg("bin2c") ) + if (cmdLine.hasArg("bin2c")) { - const char* bin2cArg = cmdLine.findOption("bin2c"); + const char *bin2cArg = cmdLine.findOption("bin2c"); if (NULL != bin2cArg) { bin2c.set(bin2cArg); @@ -2743,13 +2487,13 @@ namespace bgfx else { bin2c = baseName(outFilePath); - if (!bin2c.isEmpty() ) + if (!bin2c.isEmpty()) { - char* temp = (char*)alloca(bin2c.getLength()+1); + char *temp = (char *)alloca(bin2c.getLength() + 1); for (uint32_t ii = 0, num = bin2c.getLength(); ii < num; ++ii) { char ch = bin2c.getPtr()[ii]; - if (bx::isAlphaNum(ch) ) + if (bx::isAlphaNum(ch)) { temp[ii] = ch; } @@ -2768,7 +2512,7 @@ namespace bgfx options.depends = cmdLine.hasArg("depends"); options.preprocessOnly = cmdLine.hasArg("preprocess"); - const char* includeDir = cmdLine.findOption('i'); + const char *includeDir = cmdLine.findOption('i'); BX_TRACE("depends: %d", options.depends); BX_TRACE("preprocessOnly: %d", options.preprocessOnly); @@ -2783,21 +2527,20 @@ namespace bgfx std::string dir; { bx::FilePath fp(filePath); - bx::StringView path(fp.getPath() ); + bx::StringView path(fp.getPath()); - dir.assign(path.getPtr(), path.getTerm() ); + dir.assign(path.getPtr(), path.getTerm()); options.includeDirs.push_back(dir); } - const char* defines = cmdLine.findOption("define"); - while (NULL != defines - && '\0' != *defines) + const char *defines = cmdLine.findOption("define"); + while (NULL != defines && '\0' != *defines) { defines = bx::strLTrimSpace(defines).getPtr(); bx::StringView eol = bx::strFind(defines, ';'); - std::string define(defines, eol.getPtr() ); - options.defines.push_back(define.c_str() ); - defines = ';' == *eol.getPtr() ? eol.getPtr()+1 : eol.getPtr(); + std::string define(defines, eol.getPtr()); + options.defines.push_back(define.c_str()); + defines = ';' == *eol.getPtr() ? eol.getPtr() + 1 : eol.getPtr(); } std::string commandLineComment = "// shaderc command line:\n//"; @@ -2811,24 +2554,23 @@ namespace bgfx bool compiled = false; bx::FileReader reader; - if (!bx::open(&reader, filePath) ) + if (!bx::open(&reader, filePath)) { bx::printf("Unable to open file '%s'.\n", filePath); } else { - const char* varying = NULL; + const char *varying = NULL; File attribdef; if ('c' != options.shaderType) { std::string defaultVarying = dir + "varying.def.sc"; - const char* varyingdef = cmdLine.findOption("varyingdef", defaultVarying.c_str() ); + const char *varyingdef = cmdLine.findOption("varyingdef", defaultVarying.c_str()); attribdef.load(varyingdef); varying = attribdef.getData(); - if (NULL != varying - && *varying != '\0') + if (NULL != varying && *varying != '\0') { options.dependencies.push_back(varyingdef); } @@ -2840,30 +2582,19 @@ namespace bgfx int32_t size = (int32_t)bx::getSize(&reader); const int32_t total = size + 16384; - char* data = new char[total]; + char *data = new char[total]; size = bx::read(&reader, data, size, bx::ErrorAssert{}); // Trim UTF-8 BOM - if (data[0] == '\xef' - && data[1] == '\xbb' - && data[2] == '\xbf') + if (data[0] == '\xef' && data[1] == '\xbb' && data[2] == '\xbf') { - bx::memMove(data, &data[3], size-3); + bx::memMove(data, &data[3], size - 3); size -= 3; } const char ch = data[0]; if (false // https://en.wikipedia.org/wiki/Byte_order_mark#Byte_order_marks_by_encoding - || '\x00' == ch - || '\x0e' == ch - || '\x2b' == ch - || '\x84' == ch - || '\xdd' == ch - || '\xf7' == ch - || '\xfb' == ch - || '\xfe' == ch - || '\xff' == ch - ) + || '\x00' == ch || '\x0e' == ch || '\x2b' == ch || '\x84' == ch || '\xdd' == ch || '\xf7' == ch || '\xfb' == ch || '\xfe' == ch || '\xff' == ch) { bx::printf("Shader input file has unsupported BOM.\n"); return bx::kExitFailure; @@ -2872,15 +2603,15 @@ namespace bgfx // Compiler generates "error X3000: syntax error: unexpected end of file" // if input doesn't have empty line at EOF. data[size] = '\n'; - bx::memSet(&data[size+1], 0, total-size-1); + bx::memSet(&data[size + 1], 0, total - size - 1); bx::close(&reader); { - bx::FileWriter* writer = NULL; + bx::FileWriter *writer = NULL; if (!consoleOut) { - if (!bin2c.isEmpty() ) + if (!bin2c.isEmpty()) { writer = new Bin2cWriter(bin2c); } @@ -2889,7 +2620,7 @@ namespace bgfx writer = new bx::FileWriter; } - if (!bx::open(writer, outFilePath) ) + if (!bx::open(writer, outFilePath)) { bx::printf("Unable to open output file '%s'.\n", outFilePath); return bx::kExitFailure; @@ -2897,14 +2628,7 @@ namespace bgfx } compiled = compileShader( - varying - , commandLineComment.c_str() - , data - , size - , options - , consoleOut ? bx::getStdOut() : writer - , bx::getStdOut() - ); + varying, commandLineComment.c_str(), data, size, options, consoleOut ? bx::getStdOut() : writer, bx::getStdOut()); if (!consoleOut) { @@ -2928,42 +2652,44 @@ namespace bgfx } // namespace bgfx #ifdef ZBGFX_EMBED_SHADERC -extern "C" { - typedef int32_t (writeFce)(void* context, const void* _data, int32_t _size); - class ClbWriter : public bx::WriterI +extern "C" +{ + typedef int32_t(writeFce)(void *context, const void *_data, int32_t _size); + class ClbWriter : public bx::WriterI { public: /// - ClbWriter(void* context, writeFce* _write_fce) : m_writeFce(_write_fce), m_context(context) { - } + ClbWriter(void *context, writeFce *_write_fce) : m_writeFce(_write_fce), m_context(context) + { + } - - virtual int32_t write(const void* _data, int32_t _size, bx::Error* _err) override { - return m_writeFce(m_context, _data, _size); - } + virtual int32_t write(const void *_data, int32_t _size, bx::Error *_err) override + { + return m_writeFce(m_context, _data, _size); + } private: - writeFce* m_writeFce; - void* m_context; + writeFce *m_writeFce; + void *m_context; }; struct COptions { char shaderType; - const char* platform; - const char* profile; + const char *platform; + const char *profile; + + const char *inputFilePath; + const char *outputFilePath; - const char* inputFilePath; - const char* outputFilePath; + const char **includeDirs; + uint32_t includeDirsN; - const char** includeDirs; - uint32_t includeDirsN; + const char **defines; + uint32_t definesN; - const char** defines; - uint32_t definesN; - - const char** dependencies; - uint32_t dependenciesN; + const char **dependencies; + uint32_t dependenciesN; bool disasm; bool raw; @@ -2984,31 +2710,35 @@ extern "C" { uint32_t optimizationLevel; }; - bool zbgfx_compileShader(const char* _varying, const char* _comment, char* _shader, uint32_t _shaderLen, const COptions* _options, writeFce* _shaderWriter, void* _shaderWriterContext, writeFce* _messageWriter, void* _messageWriterContext) { - bgfx::Options options; + bool zbgfx_compileShader(const char *_varying, const char *_comment, char *_shader, uint32_t _shaderLen, const COptions *_options, writeFce *_shaderWriter, void *_shaderWriterContext, writeFce *_messageWriter, void *_messageWriterContext) + { + bgfx::Options options; - std::vector includesDirs(_options->includeDirsN); - for(int i = 0; i < _options->includeDirsN; i++) { - includesDirs.push_back(_options->includeDirs[i]); - } + std::vector includesDirs(_options->includeDirsN); + for (int i = 0; i < _options->includeDirsN; i++) + { + includesDirs.push_back(_options->includeDirs[i]); + } - std::vector defines(_options->definesN); - for(int i = 0; i < _options->definesN; i++) { - includesDirs.push_back(_options->defines[i]); - } + std::vector defines(_options->definesN); + for (int i = 0; i < _options->definesN; i++) + { + includesDirs.push_back(_options->defines[i]); + } - std::vector dependencies(_options->dependenciesN); - for(int i = 0; i < _options->dependenciesN; i++) { - includesDirs.push_back(_options->dependencies[i]); - } + std::vector dependencies(_options->dependenciesN); + for (int i = 0; i < _options->dependenciesN; i++) + { + includesDirs.push_back(_options->dependencies[i]); + } - options.shaderType = _options->shaderType; + options.shaderType = _options->shaderType; options.platform = _options->platform; options.profile = _options->profile; options.inputFilePath = _options->inputFilePath; options.outputFilePath = _options->outputFilePath; - options.includeDirs = includesDirs; - options.defines = defines; + options.includeDirs = includesDirs; + options.defines = defines; options.dependencies = dependencies; options.disasm = _options->disasm; options.raw = _options->raw; @@ -3025,19 +2755,19 @@ extern "C" { options.optimize = _options->optimize; options.optimizationLevel = _options->optimizationLevel; - ClbWriter shaderWriter(_shaderWriterContext, _shaderWriter); - ClbWriter messageWriter(_messageWriterContext, _messageWriter); + ClbWriter shaderWriter(_shaderWriterContext, _shaderWriter); + ClbWriter messageWriter(_messageWriterContext, _messageWriter); - return bgfx::compileShader(_varying, _comment, _shader, _shaderLen, options, &shaderWriter,&messageWriter); - } + return bgfx::compileShader(_varying, _comment, _shader, _shaderLen, options, &shaderWriter, &messageWriter); + } - int shaderc_main(int _argc, const char* _argv[]) + int shaderc_main(int _argc, const char *_argv[]) { return bgfx::compileShader(_argc, _argv); } } #else -int main(int _argc, const char* _argv[]) +int main(int _argc, const char *_argv[]) { return bgfx::compileShader(_argc, _argv); } diff --git a/libs/bgfx/tools/shaderc/shaderc_hlsl.cpp b/libs/bgfx/tools/shaderc/shaderc_hlsl.cpp index ac13f55..5e1a1dc 100644 --- a/libs/bgfx/tools/shaderc/shaderc_hlsl.cpp +++ b/libs/bgfx/tools/shaderc/shaderc_hlsl.cpp @@ -287,7 +287,7 @@ namespace bgfx { namespace hlsl const uint32_t D3DSIO_END = 0x0000FFFF; const uint32_t D3DSI_OPCODE_MASK = 0x0000FFFF; const uint32_t D3DSI_COMMENTSIZE_MASK = 0x7FFF0000; - const uint32_t CTAB_CONSTANT = MAKEFOURCC('C', 'T', 'A', 'B'); + const uint32_t CTAB_CONSTANT = BX_MAKEFOURCC('C', 'T', 'A', 'B'); // parse the shader blob for the constant table const size_t codeSize = _code->GetBufferSize(); diff --git a/libs/bgfx/tools/texturev/texturev.cpp b/libs/bgfx/tools/texturev/texturev.cpp index 8516e8e..6c75958 100644 --- a/libs/bgfx/tools/texturev/texturev.cpp +++ b/libs/bgfx/tools/texturev/texturev.cpp @@ -76,9 +76,10 @@ static const char* s_supportedExt[] = "exr", "gif", "gnf", - "jpg", - "jpeg", "hdr", + "heic", + "jpeg", + "jpg", "ktx", "pgm", "png", @@ -135,7 +136,9 @@ static const InputBinding s_bindingApp[] = const char* s_resetCmd = "view zoom 1.0\n" - "view rotate 0\n" + "view rotate x 0\n" + "view rotate y 0\n" + "view rotate z 0\n" "view cubemap\n" "view pan\n" "view ev\n" @@ -159,8 +162,11 @@ static const InputBinding s_bindingView[] = { entry::Key::Plus, entry::Modifier::None, 1, NULL, "view zoom +0.1" }, { entry::Key::Minus, entry::Modifier::None, 1, NULL, "view zoom -0.1" }, - { entry::Key::KeyZ, entry::Modifier::None, 1, NULL, "view rotate -90" }, - { entry::Key::KeyZ, entry::Modifier::LeftShift, 1, NULL, "view rotate +90" }, + { entry::Key::KeyZ, entry::Modifier::None, 1, NULL, "view rotate z -90" }, + { entry::Key::KeyZ, entry::Modifier::LeftShift, 1, NULL, "view rotate z +90" }, + + { entry::Key::KeyX, entry::Modifier::None, 1, NULL, "view rotate x +180" }, + { entry::Key::KeyY, entry::Modifier::None, 1, NULL, "view rotate y +180" }, { entry::Key::Up, entry::Modifier::None, 1, NULL, "view pan\n" "view file-up" }, @@ -272,7 +278,6 @@ struct View , m_angx(0.0f) , m_angy(0.0f) , m_zoom(1.0f) - , m_angle(0.0f) , m_orientation(0.0f) , m_flipH(0.0f) , m_flipV(0.0f) @@ -289,6 +294,10 @@ struct View , m_sdf(false) , m_inLinear(false) { + m_rotate[0] = 0.0f; + m_rotate[1] = 0.0f; + m_rotate[2] = 0.0f; + load(); m_textureInfo.format = bgfx::TextureFormat::Count; @@ -475,24 +484,28 @@ struct View { if (_argc >= 3) { + int8_t axis = bx::clamp(bx::toLower(_argv[2][0]) - 'x', 0, 2); + float angle; - bx::fromString(&angle, _argv[2]); + bx::fromString(&angle, _argv[3]); - if (_argv[2][0] == '+' - || _argv[2][0] == '-') + if (_argv[3][0] == '+' + || _argv[3][0] == '-') { - m_angle += bx::toRad(angle); + m_rotate[axis] += bx::toRad(angle); } else { - m_angle = bx::toRad(angle); + m_rotate[axis] = bx::toRad(angle); } - m_angle = bx::wrap(m_angle, bx::kPi*2.0f); + m_rotate[axis] = bx::wrap(m_rotate[axis], bx::kPi*2.0f); } else { - m_angle = 0.0f; + m_rotate[0] = 0.0f; + m_rotate[1] = 0.0f; + m_rotate[2] = 0.0f; } } else if (0 == bx::strCmp(_argv[1], "orientation") ) @@ -515,7 +528,8 @@ struct View { float angle; bx::fromString(&angle, _argv[3]); - *dst = bx::toRad(angle); + angle = bx::toRad(angle); + *dst = bx::wrap(angle, bx::kPi*2.0f); } else { @@ -868,7 +882,7 @@ struct View float m_angx; float m_angy; float m_zoom; - float m_angle; + float m_rotate[3]; float m_orientation; float m_flipH; float m_flipV; @@ -1450,7 +1464,9 @@ int _main_(int _argc, char** _argv) Interpolator scale(1.0f); Interpolator posx(0.0f); Interpolator posy(0.0f); - InterpolatorAngle angle(0.0f); + InterpolatorAngle rotateX(0.0f); + InterpolatorAngle rotateY(0.0f); + InterpolatorAngle rotateZ(0.0f); InterpolatorAngle angx(0.0f); InterpolatorAngle angy(0.0f); @@ -1466,7 +1482,9 @@ int _main_(int _argc, char** _argv) || scale.isActive() || posx.isActive() || posy.isActive() - || angle.isActive() + || rotateX.isActive() + || rotateY.isActive() + || rotateZ.isActive() || angx.isActive() || angy.isActive() ; @@ -1982,7 +2000,9 @@ int _main_(int _argc, char** _argv) keyBindingHelp("LMB+drag", "Pan."); keyBindingHelp("=/- or MW", "Zoom in/out."); - keyBindingHelp("z/Z", "Rotate."); + keyBindingHelp("x", "Horizontal flip (z-axis relative)."); + keyBindingHelp("y", "Vertical flip (z-axis relative)."); + keyBindingHelp("z/Z", "Rotate around Z axis."); keyBindingHelp("0", "Reset."); keyBindingHelp("1", "Fit to window."); ImGui::NextLine(); @@ -2173,7 +2193,7 @@ int _main_(int _argc, char** _argv) bgfx::dbgTextClear(); float orientation[16]; - bx::mtxRotateXYZ(orientation, view.m_flipH, view.m_flipV, angle.getValue()+view.m_orientation); + bx::mtxRotateXYZ(orientation, rotateY.getValue()+view.m_flipH, rotateX.getValue()+view.m_flipV, rotateZ.getValue()+view.m_orientation); if (view.m_fit) { @@ -2191,7 +2211,9 @@ int _main_(int _argc, char** _argv) } zoom.set(view.m_zoom, transitionTime); - angle.set(view.m_angle, transitionTime); + rotateX.set(view.m_rotate[0], transitionTime); + rotateY.set(view.m_rotate[1], transitionTime); + rotateZ.set(view.m_rotate[2], transitionTime); angx.set(view.m_angx, transitionTime); angy.set(view.m_angy, transitionTime); diff --git a/libs/bimg/3rdparty/astc-encoder/include/astcenc.h b/libs/bimg/3rdparty/astc-encoder/include/astcenc.h index c6c8c14..3d04b4e 100644 --- a/libs/bimg/3rdparty/astc-encoder/include/astcenc.h +++ b/libs/bimg/3rdparty/astc-encoder/include/astcenc.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2020-2023 Arm Limited +// Copyright 2020-2024 Arm Limited // // 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 @@ -215,6 +215,8 @@ enum astcenc_error { ASTCENC_ERR_BAD_CONTEXT, /** @brief The call failed due to unimplemented functionality. */ ASTCENC_ERR_NOT_IMPLEMENTED, + /** @brief The call failed due to an out-of-spec decode mode flag set. */ + ASTCENC_ERR_BAD_DECODE_MODE, #if defined(ASTCENC_DIAGNOSTICS) /** @brief The call failed due to an issue with diagnostic tracing. */ ASTCENC_ERR_DTRACE_FAILURE, @@ -302,6 +304,11 @@ enum astcenc_type ASTCENC_TYPE_F32 = 2 }; +/** + * @brief Function pointer type for compression progress reporting callback. + */ +extern "C" typedef void (*astcenc_progress_callback)(float); + /** * @brief Enable normal map compression. * @@ -312,6 +319,19 @@ enum astcenc_type */ static const unsigned int ASTCENC_FLG_MAP_NORMAL = 1 << 0; +/** + * @brief Enable compression heuristics that assume use of decode_unorm8 decode mode. + * + * The decode_unorm8 decode mode rounds differently to the decode_fp16 decode mode, so enabling this + * flag during compression will allow the compressor to use the correct rounding when selecting + * encodings. This will improve the compressed image quality if your application is using the + * decode_unorm8 decode mode, but will reduce image quality if using decode_fp16. + * + * Note that LDR_SRGB images will always use decode_unorm8 for the RGB channels, irrespective of + * this setting. + */ +static const unsigned int ASTCENC_FLG_USE_DECODE_UNORM8 = 1 << 1; + /** * @brief Enable alpha weighting. * @@ -378,6 +398,7 @@ static const unsigned int ASTCENC_ALL_FLAGS = ASTCENC_FLG_MAP_RGBM | ASTCENC_FLG_USE_ALPHA_WEIGHT | ASTCENC_FLG_USE_PERCEPTUAL | + ASTCENC_FLG_USE_DECODE_UNORM8 | ASTCENC_FLG_DECOMPRESS_ONLY | ASTCENC_FLG_SELF_DECOMPRESS_ONLY; @@ -550,6 +571,16 @@ struct astcenc_config */ float tune_search_mode0_enable; + /** + * @brief The progress callback, can be @c nullptr. + * + * If this is specified the codec will peridocially report progress for + * compression as a percentage between 0 and 100. The callback is called from one + * of the compressor threads, so doing significant work in the callback will + * reduce compression performance. + */ + astcenc_progress_callback progress_callback; + #if defined(ASTCENC_DIAGNOSTICS) /** * @brief The path to save the diagnostic trace data to. diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_color_unquantize.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_color_unquantize.cpp index 10fb6bc..2daa515 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_color_unquantize.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_color_unquantize.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2021 Arm Limited +// Copyright 2011-2023 Arm Limited // // 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 @@ -894,32 +894,55 @@ void unpack_color_endpoints( } } - vint4 ldr_scale(257); - vint4 hdr_scale(1); - vint4 output_scale = ldr_scale; + // Handle endpoint errors and expansion - // An LDR profile image - if ((decode_mode == ASTCENC_PRF_LDR) || - (decode_mode == ASTCENC_PRF_LDR_SRGB)) + // Linear LDR 8-bit endpoints are expanded to 16-bit by replication + if (decode_mode == ASTCENC_PRF_LDR) { - // Also matches HDR alpha, as cannot have HDR alpha without HDR RGB - if (rgb_hdr == true) + // Error color - HDR endpoint in an LDR encoding + if (rgb_hdr || alpha_hdr) { - output0 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); - output1 = vint4(0xFF00, 0x0000, 0xFF00, 0xFF00); - output_scale = hdr_scale; + output0 = vint4(0xFF, 0x00, 0xFF, 0xFF); + output1 = vint4(0xFF, 0x00, 0xFF, 0xFF); + rgb_hdr = false; + alpha_hdr = false; + } + output0 = output0 * 257; + output1 = output1 * 257; + } + // sRGB LDR 8-bit endpoints are expanded to 16 bit by: + // - RGB = shift left by 8 bits and OR with 0x80 + // - A = replication + else if (decode_mode == ASTCENC_PRF_LDR_SRGB) + { + // Error color - HDR endpoint in an LDR encoding + if (rgb_hdr || alpha_hdr) + { + output0 = vint4(0xFF, 0x00, 0xFF, 0xFF); + output1 = vint4(0xFF, 0x00, 0xFF, 0xFF); rgb_hdr = false; alpha_hdr = false; } + + vmask4 mask(true, true, true, false); + + vint4 output0rgb = lsl<8>(output0) | vint4(0x80); + vint4 output0a = output0 * 257; + output0 = select(output0a, output0rgb, mask); + + vint4 output1rgb = lsl<8>(output1) | vint4(0x80); + vint4 output1a = output1 * 257; + output1 = select(output1a, output1rgb, mask); } - // An HDR profile image + // An HDR profile decode, but may be using linear LDR endpoints + // Linear LDR 8-bit endpoints are expanded to 16-bit by replication + // HDR endpoints are already 16-bit else { vmask4 hdr_lanes(rgb_hdr, rgb_hdr, rgb_hdr, alpha_hdr); - output_scale = select(ldr_scale, hdr_scale, hdr_lanes); + vint4 output_scale = select(vint4(257), vint4(1), hdr_lanes); + output0 = output0 * output_scale; + output1 = output1 * output_scale; } - - output0 = output0 * output_scale; - output1 = output1 * output_scale; } diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_compress_symbolic.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_compress_symbolic.cpp index 0c90540..98d2495 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_compress_symbolic.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_compress_symbolic.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -247,7 +247,7 @@ static bool realign_weights_decimated( } // Create an unquantized weight grid for this decimation level - alignas(ASTCENC_VECALIGN) float uq_weightsf[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float uq_weightsf[BLOCK_MAX_WEIGHTS]; for (unsigned int we_idx = 0; we_idx < weight_count; we_idx += ASTCENC_SIMD_WIDTH) { vint unquant_value(dec_weights_uquant + we_idx); @@ -467,7 +467,7 @@ static float compress_symbolic_block_for_partition_1plane( qwt_bitcounts[i] = static_cast(bitcount); - alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; // Generate the optimized set of weights for the weight mode compute_quantized_weights_for_decimation( @@ -830,7 +830,7 @@ static float compress_symbolic_block_for_partition_2planes( unsigned int decimation_mode = bm.decimation_mode; const auto& di = bsd.get_decimation_info(decimation_mode); - alignas(ASTCENC_VECALIGN) float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float dec_weights_uquantf[BLOCK_MAX_WEIGHTS]; // Generate the optimized set of weights for the mode compute_quantized_weights_for_decimation( diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_decompress_symbolic.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_decompress_symbolic.cpp index dd331a9..7463f7e 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_decompress_symbolic.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_decompress_symbolic.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -27,15 +27,15 @@ /** * @brief Compute the integer linear interpolation of two color endpoints. * - * @param decode_mode The ASTC profile (linear or sRGB) + * @param u8_mask The mask for lanes using decode_unorm8 rather than decode_f16. * @param color0 The endpoint0 color. * @param color1 The endpoint1 color. - * @param weights The interpolation weight (between 0 and 64). + * @param weights The interpolation weight (between 0 and 64). * * @return The interpolated color. */ static vint4 lerp_color_int( - astcenc_profile decode_mode, + vmask4 u8_mask, vint4 color0, vint4 color1, vint4 weights @@ -43,24 +43,18 @@ static vint4 lerp_color_int( vint4 weight1 = weights; vint4 weight0 = vint4(64) - weight1; - if (decode_mode == ASTCENC_PRF_LDR_SRGB) - { - color0 = asr<8>(color0); - color1 = asr<8>(color1); - } - vint4 color = (color0 * weight0) + (color1 * weight1) + vint4(32); color = asr<6>(color); - if (decode_mode == ASTCENC_PRF_LDR_SRGB) - { - color = color * vint4(257); - } + // For decode_unorm8 values force the codec to bit replicate. This allows the + // rest of the codec to assume the full 0xFFFF range for everything and ignore + // the decode_mode setting + vint4 color_u8 = asr<8>(color) * vint4(257); + color = select(color, color_u8, u8_mask); return color; } - /** * @brief Convert integer color value into a float value for the decoder. * @@ -229,12 +223,13 @@ void decompress_symbolic_block( { vint4 colori(scb.constant_color); - // For sRGB decoding a real decoder would just use the top 8 bits for color conversion. - // We don't color convert, so rescale the top 8 bits into the full 16 bit dynamic range. - if (decode_mode == ASTCENC_PRF_LDR_SRGB) - { - colori = asr<8>(colori) * 257; - } + // Determine the UNORM8 rounding on the decode + vmask4 u8_mask = get_u8_component_mask(decode_mode, blk); + + // The real decoder would just use the top 8 bits, but we rescale + // in to a 16-bit value that rounds correctly. + vint4 colori_u8 = asr<8>(colori) * 257; + colori = select(colori, colori_u8, u8_mask); vint4 colorf16 = unorm16_to_sf16(colori); color = float16_to_float(colorf16); @@ -289,6 +284,8 @@ void decompress_symbolic_block( int plane2_component = scb.plane2_component; vmask4 plane2_mask = vint4::lane_id() == vint4(plane2_component); + vmask4 u8_mask = get_u8_component_mask(decode_mode, blk); + for (int i = 0; i < partition_count; i++) { // Decode the color endpoints for this partition @@ -310,7 +307,7 @@ void decompress_symbolic_block( { int tix = pi.texels_of_partition[i][j]; vint4 weight = select(vint4(plane1_weights[tix]), vint4(plane2_weights[tix]), plane2_mask); - vint4 color = lerp_color_int(decode_mode, ep0, ep1, weight); + vint4 color = lerp_color_int(u8_mask, ep0, ep1, weight); vfloat4 colorf = decode_texel(color, lns_mask); blk.data_r[tix] = colorf.lane<0>(); @@ -365,12 +362,14 @@ float compute_symbolic_block_difference_2plane( rgb_lns, a_lns, ep0, ep1); + vmask4 u8_mask = get_u8_component_mask(config.profile, blk); + // Unpack and compute error for each texel in the partition unsigned int texel_count = bsd.texel_count; for (unsigned int i = 0; i < texel_count; i++) { vint4 weight = select(vint4(plane1_weights[i]), vint4(plane2_weights[i]), plane2_mask); - vint4 colori = lerp_color_int(config.profile, ep0, ep1, weight); + vint4 colori = lerp_color_int(u8_mask, ep0, ep1, weight); vfloat4 color = int_to_float(colori); vfloat4 oldColor = blk.texel(i); @@ -444,6 +443,8 @@ float compute_symbolic_block_difference_1plane( int plane1_weights[BLOCK_MAX_TEXELS]; unpack_weights(bsd, scb, di, false, plane1_weights, nullptr); + vmask4 u8_mask = get_u8_component_mask(config.profile, blk); + vfloat4 summa = vfloat4::zero(); for (unsigned int i = 0; i < partition_count; i++) { @@ -464,7 +465,7 @@ float compute_symbolic_block_difference_1plane( for (unsigned int j = 0; j < texel_count; j++) { unsigned int tix = pi.texels_of_partition[i][j]; - vint4 colori = lerp_color_int(config.profile, ep0, ep1, + vint4 colori = lerp_color_int(u8_mask, ep0, ep1, vint4(plane1_weights[tix])); vfloat4 color = int_to_float(colori); @@ -532,7 +533,7 @@ float compute_symbolic_block_difference_1plane_1partition( const decimation_info& di = bsd.get_decimation_info(bm.decimation_mode); // Unquantize and undecimate the weights - alignas(ASTCENC_VECALIGN) int plane1_weights[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS int plane1_weights[BLOCK_MAX_TEXELS]; unpack_weights(bsd, scb, di, false, plane1_weights, nullptr); // Decode the color endpoints for this partition @@ -547,19 +548,12 @@ float compute_symbolic_block_difference_1plane_1partition( rgb_lns, a_lns, ep0, ep1); - - // Pre-shift sRGB so things round correctly - if (config.profile == ASTCENC_PRF_LDR_SRGB) - { - ep0 = asr<8>(ep0); - ep1 = asr<8>(ep1); - } + vmask4 u8_mask = get_u8_component_mask(config.profile, blk); // Unpack and compute error for each texel in the partition vfloatacc summav = vfloatacc::zero(); vint lane_id = vint::lane_id(); - vint srgb_scale(config.profile == ASTCENC_PRF_LDR_SRGB ? 257 : 1); unsigned int texel_count = bsd.texel_count; for (unsigned int i = 0; i < texel_count; i += ASTCENC_SIMD_WIDTH) @@ -578,11 +572,25 @@ float compute_symbolic_block_difference_1plane_1partition( vint ep0_b = vint(ep0.lane<2>()) * weight0; vint ep0_a = vint(ep0.lane<3>()) * weight0; - // Shift so things round correctly - vint colori_r = asr<6>(ep0_r + ep1_r + vint(32)) * srgb_scale; - vint colori_g = asr<6>(ep0_g + ep1_g + vint(32)) * srgb_scale; - vint colori_b = asr<6>(ep0_b + ep1_b + vint(32)) * srgb_scale; - vint colori_a = asr<6>(ep0_a + ep1_a + vint(32)) * srgb_scale; + // Combine contributions + vint colori_r = asr<6>(ep0_r + ep1_r + vint(32)); + vint colori_g = asr<6>(ep0_g + ep1_g + vint(32)); + vint colori_b = asr<6>(ep0_b + ep1_b + vint(32)); + vint colori_a = asr<6>(ep0_a + ep1_a + vint(32)); + + // If using a U8 decode mode bit replicate top 8 bits + // so rest of codec can assume 0xFFFF max range everywhere + vint colori_r8 = asr<8>(colori_r) * vint(257); + colori_r = select(colori_r, colori_r8, vmask(u8_mask.lane<0>())); + + vint colori_g8 = asr<8>(colori_g) * vint(257); + colori_g = select(colori_g, colori_g8, vmask(u8_mask.lane<1>())); + + vint colori_b8 = asr<8>(colori_b) * vint(257); + colori_b = select(colori_b, colori_b8, vmask(u8_mask.lane<2>())); + + vint colori_a8 = asr<8>(colori_a) * vint(257); + colori_a = select(colori_a, colori_a8, vmask(u8_mask.lane<3>())); // Compute color diff vfloat color_r = int_to_float(colori_r); diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_entry.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_entry.cpp index 03cf6a8..5dc3801 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_entry.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_entry.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -217,11 +217,13 @@ static astcenc_error validate_block_size( /** * @brief Validate flags. * - * @param flags The flags to check. + * @param profile The profile to check. + * @param flags The flags to check. * * @return Return @c ASTCENC_SUCCESS if validated, otherwise an error on failure. */ static astcenc_error validate_flags( + astcenc_profile profile, unsigned int flags ) { // Flags field must not contain any unknown flag bits @@ -239,6 +241,14 @@ static astcenc_error validate_flags( return ASTCENC_ERR_BAD_FLAGS; } + // Decode_unorm8 must only be used with an LDR profile + bool is_unorm8 = flags & ASTCENC_FLG_USE_DECODE_UNORM8; + bool is_hdr = (profile == ASTCENC_PRF_HDR) || (profile == ASTCENC_PRF_HDR_RGB_LDR_A); + if (is_unorm8 && is_hdr) + { + return ASTCENC_ERR_BAD_DECODE_MODE; + } + return ASTCENC_SUCCESS; } @@ -364,7 +374,7 @@ static astcenc_error validate_config( return status; } - status = validate_flags(config.flags); + status = validate_flags(config.profile, config.flags); if (status != ASTCENC_SUCCESS) { return status; @@ -591,7 +601,7 @@ astcenc_error astcenc_config_init( } // Flags field must not contain any unknown flag bits - status = validate_flags(flags); + status = validate_flags(profile, flags); if (status != ASTCENC_SUCCESS) { return status; @@ -689,6 +699,12 @@ astcenc_error astcenc_context_alloc( } ctx->bsd = aligned_malloc(sizeof(block_size_descriptor), ASTCENC_VECALIGN); + if (!ctx->bsd) + { + delete ctxo; + return ASTCENC_ERR_OUT_OF_MEM; + } + bool can_omit_modes = static_cast(config.flags & ASTCENC_FLG_SELF_DECOMPRESS_ONLY); init_block_size_descriptor(config.block_x, config.block_y, config.block_z, can_omit_modes, @@ -698,7 +714,7 @@ astcenc_error astcenc_context_alloc( #if !defined(ASTCENC_DECOMPRESS_ONLY) // Do setup only needed by compression - if (!(status & ASTCENC_FLG_DECOMPRESS_ONLY)) + if (!(ctx->config.flags & ASTCENC_FLG_DECOMPRESS_ONLY)) { // Turn a dB limit into a per-texel error for faster use later if ((ctx->config.profile == ASTCENC_PRF_LDR) || (ctx->config.profile == ASTCENC_PRF_LDR_SRGB)) @@ -712,7 +728,7 @@ astcenc_error astcenc_context_alloc( size_t worksize = sizeof(compression_working_buffers) * thread_count; ctx->working_buffers = aligned_malloc(worksize, ASTCENC_VECALIGN); - static_assert((sizeof(compression_working_buffers) % ASTCENC_VECALIGN) == 0, + static_assert((ASTCENC_VECALIGN == 0) || ((sizeof(compression_working_buffers) % ASTCENC_VECALIGN) == 0), "compression_working_buffers size must be multiple of vector alignment"); if (!ctx->working_buffers) { @@ -802,6 +818,8 @@ static void compress_image( int row_blocks = xblocks; int plane_blocks = xblocks * yblocks; + blk.decode_unorm8 = ctxo.context.config.flags & ASTCENC_FLG_USE_DECODE_UNORM8; + // Populate the block channel weights blk.channel_weight = vfloat4(ctx.config.cw_r_weight, ctx.config.cw_g_weight, @@ -812,7 +830,7 @@ static void compress_image( auto& temp_buffers = ctx.working_buffers[thread_index]; // Only the first thread actually runs the initializer - ctxo.manage_compress.init(block_count); + ctxo.manage_compress.init(block_count, ctx.config.progress_callback); // Determine if we can use an optimized load function bool needs_swz = (swizzle.r != ASTCENC_SWZ_R) || (swizzle.g != ASTCENC_SWZ_G) || @@ -1137,6 +1155,7 @@ astcenc_error astcenc_decompress_image( unsigned int xblocks = (image_out.dim_x + block_x - 1) / block_x; unsigned int yblocks = (image_out.dim_y + block_y - 1) / block_y; unsigned int zblocks = (image_out.dim_z + block_z - 1) / block_z; + unsigned int block_count = zblocks * yblocks * xblocks; int row_blocks = xblocks; int plane_blocks = xblocks * yblocks; @@ -1148,9 +1167,12 @@ astcenc_error astcenc_decompress_image( return ASTCENC_ERR_OUT_OF_MEM; } - image_block blk; + image_block blk {}; blk.texel_count = static_cast(block_x * block_y * block_z); + // Decode mode inferred from the output data type + blk.decode_unorm8 = image_out.data_type == ASTCENC_TYPE_U8; + // If context thread count is one then implicitly reset if (ctx->thread_count == 1) { @@ -1158,7 +1180,7 @@ astcenc_error astcenc_decompress_image( } // Only the first thread actually runs the initializer - ctxo->manage_decompress.init(zblocks * yblocks * xblocks); + ctxo->manage_decompress.init(block_count, nullptr); // All threads run this processing loop until there is no work remaining while (true) @@ -1356,6 +1378,8 @@ const char* astcenc_get_error_string( return "ASTCENC_ERR_BAD_CONTEXT"; case ASTCENC_ERR_NOT_IMPLEMENTED: return "ASTCENC_ERR_NOT_IMPLEMENTED"; + case ASTCENC_ERR_BAD_DECODE_MODE: + return "ASTCENC_ERR_BAD_DECODE_MODE"; #if defined(ASTCENC_DIAGNOSTICS) case ASTCENC_ERR_DTRACE_FAILURE: return "ASTCENC_ERR_DTRACE_FAILURE"; diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_ideal_endpoints_and_weights.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_ideal_endpoints_and_weights.cpp index 89ec9dc..051782f 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_ideal_endpoints_and_weights.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_ideal_endpoints_and_weights.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -873,7 +873,7 @@ void compute_ideal_weights_for_decimation( } // Otherwise compute an estimate and perform single refinement iteration - alignas(ASTCENC_VECALIGN) float infilled_weights[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float infilled_weights[BLOCK_MAX_TEXELS]; // Compute an initial average for each decimated weight bool constant_wes = ei.is_constant_weight_error_scale; @@ -1171,7 +1171,7 @@ void recompute_ideal_colors_1plane( promise(total_texel_count > 0); promise(partition_count > 0); - alignas(ASTCENC_VECALIGN) float dec_weight[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float dec_weight[BLOCK_MAX_WEIGHTS]; for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) { vint unquant_value(dec_weights_uquant + i); @@ -1179,7 +1179,7 @@ void recompute_ideal_colors_1plane( storea(unquant_valuef, dec_weight + i); } - alignas(ASTCENC_VECALIGN) float undec_weight[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float undec_weight[BLOCK_MAX_TEXELS]; float* undec_weight_ref; if (di.max_texel_weight_count == 1) { @@ -1394,8 +1394,8 @@ void recompute_ideal_colors_2planes( promise(total_texel_count > 0); promise(weight_count > 0); - alignas(ASTCENC_VECALIGN) float dec_weight_plane1[BLOCK_MAX_WEIGHTS_2PLANE]; - alignas(ASTCENC_VECALIGN) float dec_weight_plane2[BLOCK_MAX_WEIGHTS_2PLANE]; + ASTCENC_ALIGNAS float dec_weight_plane1[BLOCK_MAX_WEIGHTS_2PLANE]; + ASTCENC_ALIGNAS float dec_weight_plane2[BLOCK_MAX_WEIGHTS_2PLANE]; assert(weight_count <= BLOCK_MAX_WEIGHTS_2PLANE); @@ -1410,8 +1410,8 @@ void recompute_ideal_colors_2planes( storea(unquant_value2f, dec_weight_plane2 + i); } - alignas(ASTCENC_VECALIGN) float undec_weight_plane1[BLOCK_MAX_TEXELS]; - alignas(ASTCENC_VECALIGN) float undec_weight_plane2[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float undec_weight_plane1[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float undec_weight_plane2[BLOCK_MAX_TEXELS]; float* undec_weight_plane1_ref; float* undec_weight_plane2_ref; diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_image.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_image.cpp index b60d9cd..079f69f 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_image.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_image.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2022 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -109,7 +109,7 @@ static vfloat4 swz_texel( vfloat4 data, const astcenc_swizzle& swz ) { - alignas(16) float datas[6]; + ASTCENC_ALIGNAS float datas[6]; storea(data, datas); datas[ASTCENC_SWZ_0] = 0.0f; diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_integer_sequence.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_integer_sequence.cpp index 4167503..41dc38b 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_integer_sequence.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_integer_sequence.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2021 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -464,10 +464,10 @@ static inline void write_bits( } /** - * @brief Read up to 8 bits at an arbitrary bit offset. + * @brief Read up to 16 bits from two bytes. * - * The stored value is at most 8 bits, but can be stored at an offset of between 0 and 7 bits so may - * span two separate bytes in memory. + * This function reads a packed N-bit field from two bytes in memory. The stored value must exist + * within the two bytes, but can start at an arbitary bit offset and span the two bytes in memory. * * @param bitcount The number of bits to read. * @param bitoffset The bit offset to read from, between 0 and 7. diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal.h index b1da41b..df6e07f 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -29,6 +29,7 @@ #include #endif #include +#include #include "astcenc.h" #include "astcenc_mathlib.h" @@ -325,10 +326,10 @@ struct partition_info uint8_t partition_texel_count[BLOCK_MAX_PARTITIONS]; /** @brief The partition of each texel in the block. */ - uint8_t partition_of_texel[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS uint8_t partition_of_texel[BLOCK_MAX_TEXELS]; /** @brief The list of texels in each partition. */ - uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS uint8_t texels_of_partition[BLOCK_MAX_PARTITIONS][BLOCK_MAX_TEXELS]; }; /** @@ -366,40 +367,40 @@ struct decimation_info * @brief The number of weights that contribute to each texel. * Value is between 1 and 4. */ - uint8_t texel_weight_count[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS uint8_t texel_weight_count[BLOCK_MAX_TEXELS]; /** * @brief The weight index of the N weights that are interpolated for each texel. * Stored transposed to improve vectorization. */ - uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS uint8_t texel_weights_tr[4][BLOCK_MAX_TEXELS]; /** * @brief The bilinear contribution of the N weights that are interpolated for each texel. * Value is between 0 and 16, stored transposed to improve vectorization. */ - uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS uint8_t texel_weight_contribs_int_tr[4][BLOCK_MAX_TEXELS]; /** * @brief The bilinear contribution of the N weights that are interpolated for each texel. * Value is between 0 and 1, stored transposed to improve vectorization. */ - alignas(ASTCENC_VECALIGN) float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float texel_weight_contribs_float_tr[4][BLOCK_MAX_TEXELS]; /** @brief The number of texels that each stored weight contributes to. */ - uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS uint8_t weight_texel_count[BLOCK_MAX_WEIGHTS]; /** * @brief The list of texels that use a specific weight index. * Stored transposed to improve vectorization. */ - uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS uint8_t weight_texels_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; /** * @brief The bilinear contribution to the N texels that use each weight. * Value is between 0 and 1, stored transposed to improve vectorization. */ - alignas(ASTCENC_VECALIGN) float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float weights_texel_contribs_tr[BLOCK_MAX_TEXELS][BLOCK_MAX_WEIGHTS]; /** * @brief The bilinear contribution to the Nth texel that uses each weight. @@ -579,7 +580,7 @@ struct block_size_descriptor decimation_mode decimation_modes[WEIGHTS_MAX_DECIMATION_MODES]; /** @brief The active decimation tables, stored in low indices. */ - alignas(ASTCENC_VECALIGN) decimation_info decimation_tables[WEIGHTS_MAX_DECIMATION_MODES]; + ASTCENC_ALIGNAS decimation_info decimation_tables[WEIGHTS_MAX_DECIMATION_MODES]; /** @brief The packed block mode array index, or @c BLOCK_BAD_BLOCK_MODE if not active. */ uint16_t block_mode_packed_index[WEIGHTS_MAX_BLOCK_MODES]; @@ -731,7 +732,11 @@ struct block_size_descriptor * * The @c data_[rgba] fields store the image data in an encoded SoA float form designed for easy * vectorization. Input data is converted to float and stored as values between 0 and 65535. LDR - * data is stored as direct UNORM data, HDR data is stored as LNS data. + * data is stored as direct UNORM data, HDR data is stored as LNS data. They are allocated SIMD + * elements over-size to allow vectorized stores of unaligned and partial SIMD lanes (e.g. in a + * 6x6x6 block the final row write will read elements 210-217 (vec8) or 214-217 (vec4), which is + * two elements above the last real data element). The overspill values are never written to memory, + * and would be benign, but the padding avoids hitting undefined behavior. * * The @c rgb_lns and @c alpha_lns fields that assigned a per-texel use of HDR are only used during * decompression. The current compressor will always use HDR endpoint formats when in HDR mode. @@ -739,16 +744,16 @@ struct block_size_descriptor struct image_block { /** @brief The input (compress) or output (decompress) data for the red color component. */ - alignas(ASTCENC_VECALIGN) float data_r[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float data_r[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1]; /** @brief The input (compress) or output (decompress) data for the green color component. */ - alignas(ASTCENC_VECALIGN) float data_g[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float data_g[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1]; /** @brief The input (compress) or output (decompress) data for the blue color component. */ - alignas(ASTCENC_VECALIGN) float data_b[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float data_b[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1]; /** @brief The input (compress) or output (decompress) data for the alpha color component. */ - alignas(ASTCENC_VECALIGN) float data_a[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float data_a[BLOCK_MAX_TEXELS + ASTCENC_SIMD_WIDTH - 1]; /** @brief The number of texels in the block. */ uint8_t texel_count; @@ -771,6 +776,9 @@ struct image_block /** @brief Is this grayscale block where R == G == B for all texels? */ bool grayscale; + /** @brief Is the eventual decode using decode_unorm8 rounding? */ + bool decode_unorm8; + /** @brief Set to 1 if a texel is using HDR RGB endpoints (decompression only). */ uint8_t rgb_lns[BLOCK_MAX_TEXELS]; @@ -897,10 +905,10 @@ struct endpoints_and_weights endpoints ep; /** @brief The ideal weight for each texel; may be undecimated or decimated. */ - alignas(ASTCENC_VECALIGN) float weights[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float weights[BLOCK_MAX_TEXELS]; /** @brief The ideal weight error scaling for each texel; may be undecimated or decimated. */ - alignas(ASTCENC_VECALIGN) float weight_error_scale[BLOCK_MAX_TEXELS]; + ASTCENC_ALIGNAS float weight_error_scale[BLOCK_MAX_TEXELS]; }; /** @@ -930,7 +938,7 @@ struct encoding_choice_errors /** * @brief Preallocated working buffers, allocated per thread during context creation. */ -struct alignas(ASTCENC_VECALIGN) compression_working_buffers +struct ASTCENC_ALIGNAS compression_working_buffers { /** @brief Ideal endpoints and weights for plane 1. */ endpoints_and_weights ei1; @@ -946,17 +954,17 @@ struct alignas(ASTCENC_VECALIGN) compression_working_buffers * * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. */ - alignas(ASTCENC_VECALIGN) float dec_weights_ideal[WEIGHTS_MAX_DECIMATION_MODES * BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS float dec_weights_ideal[WEIGHTS_MAX_DECIMATION_MODES * BLOCK_MAX_WEIGHTS]; /** * @brief Decimated quantized weight values in the unquantized 0-64 range. * * For two planes, second plane starts at @c WEIGHTS_PLANE2_OFFSET offsets. */ - uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS uint8_t dec_weights_uquant[WEIGHTS_MAX_BLOCK_MODES * BLOCK_MAX_WEIGHTS]; /** @brief Error of the best encoding combination for each block mode. */ - alignas(ASTCENC_VECALIGN) float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES]; + ASTCENC_ALIGNAS float errors_of_best_combination[WEIGHTS_MAX_BLOCK_MODES]; /** @brief The best color quant for each block mode. */ uint8_t best_quant_levels[WEIGHTS_MAX_BLOCK_MODES]; @@ -1107,7 +1115,7 @@ struct symbolic_compressed_block * * If dual plane, the second plane starts at @c weights[WEIGHTS_PLANE2_OFFSET]. */ - uint8_t weights[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS uint8_t weights[BLOCK_MAX_WEIGHTS]; /** * @brief Get the weight quantization used by this block mode. @@ -1563,6 +1571,33 @@ unsigned int find_best_partition_candidates( Functionality for managing images and image related data. ============================================================================ */ +/** + * @brief Get a vector mask indicating lanes decompressing into a UNORM8 value. + * + * @param decode_mode The color profile for LDR_SRGB settings. + * @param blk The image block for output image bitness settings. + * + * @return The component mask vector. + */ +static inline vmask4 get_u8_component_mask( + astcenc_profile decode_mode, + const image_block& blk +) { + vmask4 u8_mask(false); + // Decode mode writing to a unorm8 output value + if (blk.decode_unorm8) + { + u8_mask = vmask4(true); + } + // SRGB writing to a unorm8 RGB value + else if (decode_mode == ASTCENC_PRF_LDR_SRGB) + { + u8_mask = vmask4(true, true, true, false); + } + + return u8_mask; +} + /** * @brief Setup computation of regional averages in an image. * @@ -1816,7 +1851,7 @@ uint8_t pack_color_endpoints( * * Endpoints must be unscrambled and converted into the 0-255 range before calling this functions. * - * @param decode_mode The decode mode (LDR, HDR). + * @param decode_mode The decode mode (LDR, HDR, etc). * @param format The color endpoint mode used. * @param input The raw array of encoded input integers. The length of this array * depends on @c format; it can be safely assumed to be large enough. @@ -2142,10 +2177,11 @@ Platform-specific functions. /** * @brief Allocate an aligned memory buffer. * - * Allocated memory must be freed by aligned_free; + * Allocated memory must be freed by aligned_free. * * @param size The desired buffer size. - * @param align The desired buffer alignment; must be 2^N. + * @param align The desired buffer alignment; must be 2^N, may be increased + * by the implementation to a minimum allowable alignment. * * @return The memory buffer pointer or nullptr on allocation failure. */ @@ -2155,10 +2191,14 @@ T* aligned_malloc(size_t size, size_t align) void* ptr; int error = 0; + // Don't allow this to under-align a type + size_t min_align = astc::max(alignof(T), sizeof(void*)); + size_t real_align = astc::max(min_align, align); + #if defined(_WIN32) - ptr = _aligned_malloc(size, align); + ptr = _aligned_malloc(size, real_align); #else - error = posix_memalign(&ptr, align, size); + error = posix_memalign(&ptr, real_align, size); #endif if (error || (!ptr)) diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal_entry.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal_entry.h index 4e87945..c283c5a 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal_entry.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_internal_entry.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2022 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -118,6 +118,18 @@ class ParallelManager /** @brief Number of tasks that need to be processed. */ unsigned int m_task_count; + /** @brief Progress callback (optional). */ + astcenc_progress_callback m_callback; + + /** @brief Lock used for callback synchronization. */ + std::mutex m_callback_lock; + + /** @brief Minimum progress before making a callback. */ + float m_callback_min_diff; + + /** @brief Last progress callback value. */ + float m_callback_last_value; + public: /** @brief Create a new ParallelManager. */ ParallelManager() @@ -138,6 +150,9 @@ class ParallelManager m_start_count = 0; m_done_count = 0; m_task_count = 0; + m_callback = nullptr; + m_callback_last_value = 0.0f; + m_callback_min_diff = 1.0f; } /** @@ -166,14 +181,20 @@ class ParallelManager * initialization. Other threads will block and wait for it to complete. * * @param task_count Total number of tasks needing processing. + * @param callback Function pointer for progress status callbacks. */ - void init(unsigned int task_count) + void init(unsigned int task_count, astcenc_progress_callback callback) { std::lock_guard lck(m_lock); if (!m_init_done) { + m_callback = callback; m_task_count = task_count; m_init_done = true; + + // Report every 1% or 4096 blocks, whichever is larger, to avoid callback overhead + float min_diff = (4096.0f / static_cast(task_count)) * 100.0f; + m_callback_min_diff = astc::max(min_diff, 1.0f); } } @@ -212,12 +233,49 @@ class ParallelManager { // Note: m_done_count cannot use an atomic without the mutex; this has a race between the // update here and the wait() for other threads - std::unique_lock lck(m_lock); - this->m_done_count += count; - if (m_done_count == m_task_count) + unsigned int local_count; + float local_last_value; { - lck.unlock(); - m_complete.notify_all(); + std::unique_lock lck(m_lock); + m_done_count += count; + local_count = m_done_count; + local_last_value = m_callback_last_value; + + if (m_done_count == m_task_count) + { + // Ensure the progress bar hits 100% + if (m_callback) + { + std::unique_lock cblck(m_callback_lock); + m_callback(100.0f); + m_callback_last_value = 100.0f; + } + + lck.unlock(); + m_complete.notify_all(); + } + } + + // Process progress callback if we have one + if (m_callback) + { + // Initial lockless test - have we progressed enough to emit? + float num = static_cast(local_count); + float den = static_cast(m_task_count); + float this_value = (num / den) * 100.0f; + bool report_test = (this_value - local_last_value) > m_callback_min_diff; + + // Recheck under lock, because another thread might report first + if (report_test) + { + std::unique_lock cblck(m_callback_lock); + bool report_retest = (this_value - m_callback_last_value) > m_callback_min_diff; + if (report_retest) + { + m_callback(this_value); + m_callback_last_value = this_value; + } + } } } diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib.h index 0540c4f..562d659 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2021 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -73,10 +73,22 @@ #endif #endif +// Force vector-sized SIMD alignment #if ASTCENC_AVX #define ASTCENC_VECALIGN 32 -#else +#elif ASTCENC_SSE || ASTCENC_NEON #define ASTCENC_VECALIGN 16 +// Use default alignment for non-SIMD builds +#else + #define ASTCENC_VECALIGN 0 +#endif + +// C++11 states that alignas(0) should be ignored but GCC doesn't do +// this on some versions, so workaround and avoid emitting alignas(0) +#if ASTCENC_VECALIGN > 0 + #define ASTCENC_ALIGNAS alignas(ASTCENC_VECALIGN) +#else + #define ASTCENC_ALIGNAS #endif #if ASTCENC_SSE != 0 || ASTCENC_AVX != 0 || ASTCENC_POPCNT != 0 diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib_softfloat.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib_softfloat.cpp index fa66036..42db764 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib_softfloat.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_mathlib_softfloat.cpp @@ -15,13 +15,13 @@ // under the License. // ---------------------------------------------------------------------------- -#include "astcenc_mathlib.h" - /** * @brief Soft-float library for IEEE-754. */ #if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0) +#include "astcenc_mathlib.h" + /* sized soft-float types. These are mapped to the sized integer types of C99, instead of C's floating-point types; this is because the library needs to maintain exact, bit-level control on all diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_symbolic_physical.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_symbolic_physical.cpp index c4da678..45d9abb 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_symbolic_physical.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_symbolic_physical.cpp @@ -330,12 +330,14 @@ void physical_to_symbolic( return; } + // Low values span 3 bytes so need two read_bits calls int vx_low_s = read_bits(8, 12, pcb) | (read_bits(5, 12 + 8, pcb) << 8); - int vx_high_s = read_bits(8, 25, pcb) | (read_bits(5, 25 + 8, pcb) << 8); + int vx_high_s = read_bits(13, 25, pcb); int vx_low_t = read_bits(8, 38, pcb) | (read_bits(5, 38 + 8, pcb) << 8); - int vx_high_t = read_bits(8, 51, pcb) | (read_bits(5, 51 + 8, pcb) << 8); + int vx_high_t = read_bits(13, 51, pcb); - int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && vx_low_t == 0x1FFF && vx_high_t == 0x1FFF; + int all_ones = vx_low_s == 0x1FFF && vx_high_s == 0x1FFF && + vx_low_t == 0x1FFF && vx_high_t == 0x1FFF; if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t) && !all_ones) { @@ -350,12 +352,14 @@ void physical_to_symbolic( int vx_high_s = read_bits(9, 19, pcb); int vx_low_t = read_bits(9, 28, pcb); int vx_high_t = read_bits(9, 37, pcb); - int vx_low_p = read_bits(9, 46, pcb); - int vx_high_p = read_bits(9, 55, pcb); + int vx_low_r = read_bits(9, 46, pcb); + int vx_high_r = read_bits(9, 55, pcb); - int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && vx_low_t == 0x1FF && vx_high_t == 0x1FF && vx_low_p == 0x1FF && vx_high_p == 0x1FF; + int all_ones = vx_low_s == 0x1FF && vx_high_s == 0x1FF && + vx_low_t == 0x1FF && vx_high_t == 0x1FF && + vx_low_r == 0x1FF && vx_high_r == 0x1FF; - if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_p >= vx_high_p) && !all_ones) + if ((vx_low_s >= vx_high_s || vx_low_t >= vx_high_t || vx_low_r >= vx_high_r) && !all_ones) { scb.block_type = SYM_BTYPE_ERROR; return; @@ -470,8 +474,7 @@ void physical_to_symbolic( bitpos += 2; } } - scb.partition_index = static_cast(read_bits(6, 13, pcb) | - (read_bits(PARTITION_INDEX_BITS - 6, 19, pcb) << 6)); + scb.partition_index = static_cast(read_bits(10, 13, pcb)); } for (int i = 0; i < partition_count; i++) diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_avx2_8.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_avx2_8.h index 72ed19f..3ca25e3 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_avx2_8.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_avx2_8.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2019-2022 Arm Limited +// Copyright 2019-2024 Arm Limited // // 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 @@ -1170,7 +1170,7 @@ ASTCENC_SIMD_INLINE void store_lanes_masked(uint8_t* base, vint8 data, vmask8 ma */ ASTCENC_SIMD_INLINE void print(vint8 a) { - alignas(ASTCENC_VECALIGN) int v[8]; + alignas(32) int v[8]; storea(a, v); printf("v8_i32:\n %8d %8d %8d %8d %8d %8d %8d %8d\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); @@ -1181,7 +1181,7 @@ ASTCENC_SIMD_INLINE void print(vint8 a) */ ASTCENC_SIMD_INLINE void printx(vint8 a) { - alignas(ASTCENC_VECALIGN) int v[8]; + alignas(32) int v[8]; storea(a, v); printf("v8_i32:\n %08x %08x %08x %08x %08x %08x %08x %08x\n", v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); @@ -1192,7 +1192,7 @@ ASTCENC_SIMD_INLINE void printx(vint8 a) */ ASTCENC_SIMD_INLINE void print(vfloat8 a) { - alignas(ASTCENC_VECALIGN) float v[8]; + alignas(32) float v[8]; storea(a, v); printf("v8_f32:\n %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f %0.4f\n", static_cast(v[0]), static_cast(v[1]), diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_common_4.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_common_4.h index 86ee4fd..1e04367 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_common_4.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_common_4.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2020-2021 Arm Limited +// Copyright 2020-2024 Arm Limited // // 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 @@ -383,7 +383,7 @@ static ASTCENC_SIMD_INLINE void bit_transfer_signed( */ ASTCENC_SIMD_INLINE void print(vint4 a) { - alignas(16) int v[4]; + ASTCENC_ALIGNAS int v[4]; storea(a, v); printf("v4_i32:\n %8d %8d %8d %8d\n", v[0], v[1], v[2], v[3]); @@ -394,7 +394,7 @@ ASTCENC_SIMD_INLINE void print(vint4 a) */ ASTCENC_SIMD_INLINE void printx(vint4 a) { - alignas(16) int v[4]; + ASTCENC_ALIGNAS int v[4]; storea(a, v); printf("v4_i32:\n %08x %08x %08x %08x\n", v[0], v[1], v[2], v[3]); @@ -405,7 +405,7 @@ ASTCENC_SIMD_INLINE void printx(vint4 a) */ ASTCENC_SIMD_INLINE void print(vfloat4 a) { - alignas(16) float v[4]; + ASTCENC_ALIGNAS float v[4]; storea(a, v); printf("v4_f32:\n %0.4f %0.4f %0.4f %0.4f\n", static_cast(v[0]), static_cast(v[1]), diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_neon_4.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_neon_4.h index c5ad872..42545e7 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_neon_4.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_neon_4.h @@ -359,9 +359,9 @@ struct vmask4 /** * @brief Get the scalar from a single lane. */ - template ASTCENC_SIMD_INLINE uint32_t lane() const + template ASTCENC_SIMD_INLINE bool lane() const { - return vgetq_lane_u32(m, l); + return vgetq_lane_u32(m, l) != 0; } /** diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_none_4.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_none_4.h index 6dbb659..be7348e 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_none_4.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_none_4.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2019-2022 Arm Limited +// Copyright 2019-2024 Arm Limited // // 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 @@ -351,6 +351,13 @@ struct vmask4 m[3] = d == false ? 0 : -1; } + /** + * @brief Get the scalar value of a single lane. + */ + template ASTCENC_SIMD_INLINE float lane() const + { + return m[l] != 0; + } /** * @brief The vector ... @@ -549,10 +556,16 @@ ASTCENC_SIMD_INLINE vmask4 operator>(vint4 a, vint4 b) */ template ASTCENC_SIMD_INLINE vint4 lsl(vint4 a) { - return vint4(a.m[0] << s, - a.m[1] << s, - a.m[2] << s, - a.m[3] << s); + // Cast to unsigned to avoid shift in/out of sign bit undefined behavior + unsigned int as0 = static_cast(a.m[0]) << s; + unsigned int as1 = static_cast(a.m[1]) << s; + unsigned int as2 = static_cast(a.m[2]) << s; + unsigned int as3 = static_cast(a.m[3]) << s; + + return vint4(static_cast(as0), + static_cast(as1), + static_cast(as2), + static_cast(as3)); } /** @@ -560,6 +573,7 @@ template ASTCENC_SIMD_INLINE vint4 lsl(vint4 a) */ template ASTCENC_SIMD_INLINE vint4 lsr(vint4 a) { + // Cast to unsigned to avoid shift in/out of sign bit undefined behavior unsigned int as0 = static_cast(a.m[0]) >> s; unsigned int as1 = static_cast(a.m[1]) >> s; unsigned int as2 = static_cast(a.m[2]) >> s; diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_sse_4.h b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_sse_4.h index 4dd58d2..3dce5ba 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_sse_4.h +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_vecmathlib_sse_4.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2019-2022 Arm Limited +// Copyright 2019-2023 Arm Limited // // 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 @@ -379,9 +379,9 @@ struct vmask4 /** * @brief Get the scalar value of a single lane. */ - template ASTCENC_SIMD_INLINE float lane() const + template ASTCENC_SIMD_INLINE bool lane() const { - return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l)); + return _mm_cvtss_f32(_mm_shuffle_ps(m, m, l)) != 0.0f; } /** diff --git a/libs/bimg/3rdparty/astc-encoder/source/astcenc_weight_align.cpp b/libs/bimg/3rdparty/astc-encoder/source/astcenc_weight_align.cpp index aa6ab61..4e993e7 100644 --- a/libs/bimg/3rdparty/astc-encoder/source/astcenc_weight_align.cpp +++ b/libs/bimg/3rdparty/astc-encoder/source/astcenc_weight_align.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2023 Arm Limited +// Copyright 2011-2024 Arm Limited // // 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 @@ -60,8 +60,8 @@ static const uint8_t steps_for_quant_level[12] { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32 }; -alignas(ASTCENC_VECALIGN) static float sin_table[SINCOS_STEPS][ANGULAR_STEPS]; -alignas(ASTCENC_VECALIGN) static float cos_table[SINCOS_STEPS][ANGULAR_STEPS]; +ASTCENC_ALIGNAS static float sin_table[SINCOS_STEPS][ANGULAR_STEPS]; +ASTCENC_ALIGNAS static float cos_table[SINCOS_STEPS][ANGULAR_STEPS]; #if defined(ASTCENC_DIAGNOSTICS) static bool print_once { true }; @@ -99,7 +99,7 @@ static void compute_angular_offsets( promise(weight_count > 0); promise(max_angular_steps > 0); - alignas(ASTCENC_VECALIGN) int isamplev[BLOCK_MAX_WEIGHTS]; + ASTCENC_ALIGNAS int isamplev[BLOCK_MAX_WEIGHTS]; // Precompute isample; arrays are always allocated 64 elements long for (unsigned int i = 0; i < weight_count; i += ASTCENC_SIMD_WIDTH) @@ -242,16 +242,16 @@ static void compute_angular_endpoints_for_quant_levels( unsigned int max_quant_steps = steps_for_quant_level[max_quant_level]; unsigned int max_angular_steps = steps_for_quant_level[max_quant_level]; - alignas(ASTCENC_VECALIGN) float angular_offsets[ANGULAR_STEPS]; + ASTCENC_ALIGNAS float angular_offsets[ANGULAR_STEPS]; compute_angular_offsets(weight_count, dec_weight_ideal_value, max_angular_steps, angular_offsets); - alignas(ASTCENC_VECALIGN) float lowest_weight[ANGULAR_STEPS]; - alignas(ASTCENC_VECALIGN) int32_t weight_span[ANGULAR_STEPS]; - alignas(ASTCENC_VECALIGN) float error[ANGULAR_STEPS]; - alignas(ASTCENC_VECALIGN) float cut_low_weight_error[ANGULAR_STEPS]; - alignas(ASTCENC_VECALIGN) float cut_high_weight_error[ANGULAR_STEPS]; + ASTCENC_ALIGNAS float lowest_weight[ANGULAR_STEPS]; + ASTCENC_ALIGNAS int32_t weight_span[ANGULAR_STEPS]; + ASTCENC_ALIGNAS float error[ANGULAR_STEPS]; + ASTCENC_ALIGNAS float cut_low_weight_error[ANGULAR_STEPS]; + ASTCENC_ALIGNAS float cut_high_weight_error[ANGULAR_STEPS]; compute_lowest_and_highest_weight(weight_count, dec_weight_ideal_value, max_angular_steps, max_quant_steps, diff --git a/libs/bimg/src/config.h b/libs/bimg/src/config.h index 114f813..91cb481 100644 --- a/libs/bimg/src/config.h +++ b/libs/bimg/src/config.h @@ -56,4 +56,8 @@ # define BIMG_DECODE_ETC2 BIMG_DECODE_ENABLE #endif // BIMG_DECODE_ETC2 +#ifndef BIMG_DECODE_HEIF +# define BIMG_DECODE_HEIF 0 +#endif // BIMG_DECODE_HEIF + #endif // BIMG_CONFIG_H_HEADER_GUARD diff --git a/libs/bimg/src/image_decode.cpp b/libs/bimg/src/image_decode.cpp index f0bedd2..ddf16e7 100644 --- a/libs/bimg/src/image_decode.cpp +++ b/libs/bimg/src/image_decode.cpp @@ -34,6 +34,10 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4334) // warning C4334: '<<' : result of 32 - #include BX_PRAGMA_DIAGNOSTIC_POP(); +#if BIMG_DECODE_HEIF +# include +#endif // BIMG_DECODE_HEIF + void* lodepng_malloc(size_t _size) { return ::malloc(_size); @@ -632,7 +636,6 @@ namespace bimg output->m_hasAlpha = hasAlpha; } - return output; } @@ -679,8 +682,8 @@ namespace bimg ImageContainer* output = imageAlloc(_allocator , format - , uint16_t(width) - , uint16_t(height) + , bx::narrowCast(width) + , bx::narrowCast(height) , 0 , 1 , false @@ -828,6 +831,57 @@ namespace bimg return image; } + static ImageContainer* imageParseLibHeif(bx::AllocatorI* _allocator, const void* _data, uint32_t _size, bx::Error* _err) + { +#if BIMG_DECODE_HEIF + heif_context* ctx = heif_context_alloc(); + + heif_context_read_from_memory_without_copy(ctx, _data, _size, NULL); + + heif_image_handle* handle; + heif_context_get_primary_image_handle(ctx, &handle); + + heif_image* image; + heif_decode_image(handle, &image, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, NULL); + + int32_t srcStride; + const uint8_t* data = heif_image_get_plane_readonly(image, heif_channel_interleaved, &srcStride); + + ImageContainer* output = NULL; + if (NULL != data) + { + const bimg::TextureFormat::Enum format = bimg::TextureFormat::RGBA8; + const int32_t width = heif_image_handle_get_width(handle); + const int32_t height = heif_image_handle_get_height(handle); + const int32_t dstStride = width*4; + + output = imageAlloc(_allocator + , format + , bx::narrowCast(width) + , bx::narrowCast(height) + , 0 + , 1 + , false + , false + , NULL + ); + + bx::memCopy(output->m_data, dstStride, data, srcStride, dstStride, height); + } + + heif_image_release(image); + heif_image_handle_release(handle); + + heif_context_free(ctx); + + BX_UNUSED(_err); + return output; +#else + BX_UNUSED(_allocator, _data, _size, _err); + return NULL; +#endif // BIMG_DECODE_HEIF + } + ImageContainer* imageParse(bx::AllocatorI* _allocator, const void* _data, uint32_t _size, TextureFormat::Enum _dstFormat, bx::Error* _err) { BX_ERROR_SCOPE(_err); @@ -840,6 +894,7 @@ namespace bimg input = NULL == input ? imageParseTinyExr (_allocator, _data, _size, _err) : input; input = NULL == input ? imageParseJpeg (_allocator, _data, _size, _err) : input; input = NULL == input ? imageParseStbImage(_allocator, _data, _size, _err) : input; + input = NULL == input ? imageParseLibHeif (_allocator, _data, _size, _err) : input; if (NULL == input) { diff --git a/libs/bx/README.md b/libs/bx/README.md index 4af60c4..19e4e8f 100644 --- a/libs/bx/README.md +++ b/libs/bx/README.md @@ -6,6 +6,12 @@ Base X-platform library. [![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) +Goals: + + - Provide OS/runtime/compiler independent core functionality to be able to + write cross-platform applications. + - Compile without C Runtime (CRT) and without C++ Standard Library (STL). + Contact ------- diff --git a/libs/bx/include/bx/bx.h b/libs/bx/include/bx/bx.h index 361bf59..8da9816 100644 --- a/libs/bx/include/bx/bx.h +++ b/libs/bx/include/bx/bx.h @@ -117,7 +117,7 @@ namespace bx /// /// @param[in] _location Source code location where function is called. /// @param[in] _format Printf style format. - /// @param[in] ... Arguments for `_format` specification. + /// @param[in] _argList Arguments for `_format` specification. /// /// @returns True if assert should stop code execution, otherwise returns false. /// @@ -127,6 +127,8 @@ namespace bx /// /// @param[in] _assertHandlerFn Pointer to AssertHandlerFn function. /// + /// @remarks It can be set only once. This is usually done on application startup. + /// void setAssertHandler(AssertHandlerFn _assertHandlerFn); /// Assert function calls AssertHandlerFn. diff --git a/libs/bx/include/bx/constants.h b/libs/bx/include/bx/constants.h index 9c6f4c8..5d8d011 100644 --- a/libs/bx/include/bx/constants.h +++ b/libs/bx/include/bx/constants.h @@ -20,9 +20,12 @@ namespace bx /// The ratio of a circle's circumference to its radius. Pi multiplied by 2, or Tau. pi*2 constexpr float kPi2 = 6.2831853071795864769252867665590f; - /// The reciprocal of pi. 1/pi + /// The reciprocal of kPi. 1/kPi constexpr float kInvPi = 1.0f/kPi; + /// The reciprocal of kPi2. 1/kPi2 + constexpr float kInvPi2 = 1.0f/kPi2; + /// Pi divided by two. pi/2 constexpr float kPiHalf = 1.5707963267948966192313216916398f; diff --git a/libs/bx/include/bx/inline/cpu.inl b/libs/bx/include/bx/inline/cpu.inl index e95fd5c..bc0e64e 100644 --- a/libs/bx/include/bx/inline/cpu.inl +++ b/libs/bx/include/bx/inline/cpu.inl @@ -70,7 +70,7 @@ namespace bx #if BX_COMPILER_MSVC _ReadBarrier(); #else - asm volatile("":::"memory"); + __atomic_thread_fence(__ATOMIC_RELEASE); #endif // BX_COMPILER_* } @@ -79,7 +79,7 @@ namespace bx #if BX_COMPILER_MSVC _WriteBarrier(); #else - asm volatile("":::"memory"); + __atomic_thread_fence(__ATOMIC_ACQUIRE); #endif // BX_COMPILER_* } @@ -88,7 +88,7 @@ namespace bx #if BX_COMPILER_MSVC _ReadWriteBarrier(); #else - asm volatile("":::"memory"); + __atomic_thread_fence(__ATOMIC_ACQ_REL); #endif // BX_COMPILER_* } diff --git a/libs/bx/include/bx/inline/math.inl b/libs/bx/include/bx/inline/math.inl index f5b94c4..826b8f9 100644 --- a/libs/bx/include/bx/inline/math.inl +++ b/libs/bx/include/bx/inline/math.inl @@ -162,6 +162,20 @@ namespace bx return _a * _a; } + inline void sinCosApprox(float& _outSinApprox, float& _outCos, float _a) + { + const float aa = _a - floor(_a*kInvPi2)*kPi2; + const float absA = abs(aa); + const float cosA = cos(absA); + const float cosASq = square(cosA); + const float tmp0 = sqrt(1.0f - cosASq); + const float tmp1 = aa > 0.0f && aa < kPi ? 1.0f : -1.0f; + const float sinA = mul(tmp0, tmp1); + + _outSinApprox = sinA; + _outCos = cosA; + } + inline BX_CONST_FUNC float sin(float _a) { return cos(_a - kPiHalf); diff --git a/libs/bx/include/bx/inline/readerwriter.inl b/libs/bx/include/bx/inline/readerwriter.inl index 4d3148d..dd5cef2 100644 --- a/libs/bx/include/bx/inline/readerwriter.inl +++ b/libs/bx/include/bx/inline/readerwriter.inl @@ -308,7 +308,7 @@ namespace bx memSet(temp, _byte, blockSize); int32_t size = 0; - while (0 < _size) + while (0 < _size && _err->isOk() ) { int32_t bytes = write(_writer, temp, uint32_min(blockSize, _size), _err); size += bytes; diff --git a/libs/bx/include/bx/inline/typetraits.inl b/libs/bx/include/bx/inline/typetraits.inl index 6614279..8344f18 100644 --- a/libs/bx/include/bx/inline/typetraits.inl +++ b/libs/bx/include/bx/inline/typetraits.inl @@ -464,6 +464,58 @@ namespace bx return IsUnsignedT::value; } + //--- + template struct MakeSignedT { using Type = Ty; }; + template using MakeSignedType = typename MakeSignedT::Type; + + template struct MakeSignedT : AddConstT > {}; + template struct MakeSignedT : AddVolatileT> {}; + template struct MakeSignedT : AddCvT > {}; + + template<> struct MakeSignedT< char > { using Type = signed char; }; + template<> struct MakeSignedT< signed char > { using Type = signed char; }; + template<> struct MakeSignedT { using Type = signed char; }; + template<> struct MakeSignedT< short > { using Type = signed short; }; + template<> struct MakeSignedT { using Type = signed short; }; + template<> struct MakeSignedT< int > { using Type = signed int; }; + template<> struct MakeSignedT { using Type = signed int; }; + template<> struct MakeSignedT< long > { using Type = signed long; }; + template<> struct MakeSignedT { using Type = signed long; }; + template<> struct MakeSignedT< long long> { using Type = signed long long; }; + template<> struct MakeSignedT { using Type = signed long long; }; + + template + inline constexpr auto asSigned(Ty _value) + { + return MakeSignedType(_value); + } + + //--- + template struct MakeUnsignedT { using Type = Ty; }; + template using MakeUnsignedType = typename MakeUnsignedT::Type; + + template struct MakeUnsignedT : AddConstT > {}; + template struct MakeUnsignedT : AddVolatileT> {}; + template struct MakeUnsignedT : AddCvT > {}; + + template<> struct MakeUnsignedT< char > { using Type = unsigned char; }; + template<> struct MakeUnsignedT< signed char > { using Type = unsigned char; }; + template<> struct MakeUnsignedT { using Type = unsigned char; }; + template<> struct MakeUnsignedT< short > { using Type = unsigned short; }; + template<> struct MakeUnsignedT { using Type = unsigned short; }; + template<> struct MakeUnsignedT< int > { using Type = unsigned int; }; + template<> struct MakeUnsignedT { using Type = unsigned int; }; + template<> struct MakeUnsignedT< long > { using Type = unsigned long; }; + template<> struct MakeUnsignedT { using Type = unsigned long; }; + template<> struct MakeUnsignedT< long long> { using Type = unsigned long long; }; + template<> struct MakeUnsignedT { using Type = unsigned long long; }; + + template + inline constexpr auto asUnsigned(Ty _value) + { + return MakeUnsignedType(_value); + } + //--- template struct IsIntegerT : FalseConstant {}; template<> struct IsIntegerT : TrueConstant {}; diff --git a/libs/bx/include/bx/macros.h b/libs/bx/include/bx/macros.h index 62fbd19..f488f17 100644 --- a/libs/bx/include/bx/macros.h +++ b/libs/bx/include/bx/macros.h @@ -10,17 +10,7 @@ #ifndef BX_MACROS_H_HEADER_GUARD #define BX_MACROS_H_HEADER_GUARD -/// -#if BX_COMPILER_MSVC -// Workaround MSVS bug... -# define BX_VA_ARGS_PASS(...) BX_VA_ARGS_PASS_1_ __VA_ARGS__ BX_VA_ARGS_PASS_2_ -# define BX_VA_ARGS_PASS_1_ ( -# define BX_VA_ARGS_PASS_2_ ) -#else -# define BX_VA_ARGS_PASS(...) (__VA_ARGS__) -#endif // BX_COMPILER_MSVC - -#define BX_VA_ARGS_COUNT(...) BX_VA_ARGS_COUNT_ BX_VA_ARGS_PASS(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) +#define BX_VA_ARGS_COUNT(...) BX_VA_ARGS_COUNT_(__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define BX_VA_ARGS_COUNT_(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12, _a13, _a14, _a15, _a16, _last, ...) _last /// @@ -69,18 +59,13 @@ # define BX_UNREACHABLE __builtin_unreachable() # define BX_NO_VTABLE # define BX_PRINTF_ARGS(_format, _args) __attribute__( (format(__printf__, _format, _args) ) ) - -# if BX_CLANG_HAS_FEATURE(cxx_thread_local) \ - || (!BX_PLATFORM_OSX && (BX_COMPILER_GCC >= 40200) ) \ - || (BX_COMPILER_GCC >= 40500) -# define BX_THREAD_LOCAL __thread -# endif // BX_COMPILER_GCC - +# define BX_THREAD_LOCAL __thread # define BX_ATTRIBUTE(_x) __attribute__( (_x) ) # if BX_CRT_MSVC # define __stdcall # endif // BX_CRT_MSVC + #elif BX_COMPILER_MSVC # define BX_ASSUME(_condition) __assume(_condition) # define BX_ALIGN_DECL(_align, _decl) __declspec(align(_align) ) _decl @@ -137,12 +122,7 @@ #define BX_UNUSED_11(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11) BX_UNUSED_10(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10); BX_UNUSED_1(_a11) #define BX_UNUSED_12(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11, _a12) BX_UNUSED_11(_a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8, _a9, _a10, _a11); BX_UNUSED_1(_a12) -#if BX_COMPILER_MSVC -// Workaround MSVS bug... -# define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__) BX_VA_ARGS_PASS(__VA_ARGS__) -#else -# define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__)(__VA_ARGS__) -#endif // BX_COMPILER_MSVC +#define BX_UNUSED(...) BX_MACRO_DISPATCHER(BX_UNUSED_, __VA_ARGS__)(__VA_ARGS__) /// #if BX_COMPILER_CLANG @@ -155,7 +135,7 @@ # define BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG(_x) #endif // BX_COMPILER_CLANG -#if BX_COMPILER_GCC && BX_COMPILER_GCC >= 40600 +#if BX_COMPILER_GCC # define BX_PRAGMA_DIAGNOSTIC_PUSH_GCC_() _Pragma("GCC diagnostic push") # define BX_PRAGMA_DIAGNOSTIC_POP_GCC_() _Pragma("GCC diagnostic pop") # define BX_PRAGMA_DIAGNOSTIC_IGNORED_GCC(_x) _Pragma(BX_STRINGIZE(GCC diagnostic ignored _x) ) @@ -217,12 +197,7 @@ #define BX_CLASS_2(_class, _a1, _a2) BX_CLASS_1(_class, _a1); BX_CLASS_1(_class, _a2) #define BX_CLASS_3(_class, _a1, _a2, _a3) BX_CLASS_2(_class, _a1, _a2); BX_CLASS_1(_class, _a3) #define BX_CLASS_4(_class, _a1, _a2, _a3, _a4) BX_CLASS_3(_class, _a1, _a2, _a3); BX_CLASS_1(_class, _a4) - -#if BX_COMPILER_MSVC -# define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__) BX_VA_ARGS_PASS(_class, __VA_ARGS__) -#else -# define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__)(_class, __VA_ARGS__) -#endif // BX_COMPILER_MSVC +#define BX_CLASS(_class, ...) BX_MACRO_DISPATCHER(BX_CLASS_, __VA_ARGS__)(_class, __VA_ARGS__) #ifndef BX_ASSERT # if BX_CONFIG_DEBUG @@ -285,7 +260,7 @@ #define _BX_ASSERT(_condition, _format, ...) \ BX_MACRO_BLOCK_BEGIN \ if (!BX_IGNORE_C4127(_condition) \ - && bx::assertFunction(bx::Location::current(), "ASSERT " #_condition " -> " _format, ##__VA_ARGS__) ) \ + && bx::assertFunction(bx::Location::current(), "ASSERT %s -> " _format, #_condition, ##__VA_ARGS__) ) \ { \ bx::debugBreak(); \ } \ @@ -294,7 +269,7 @@ #define _BX_ASSERT_LOC(_location, _condition, _format, ...) \ BX_MACRO_BLOCK_BEGIN \ if (!BX_IGNORE_C4127(_condition) \ - && bx::assertFunction(_location, "ASSERT " #_condition " -> " _format, ##__VA_ARGS__) ) \ + && bx::assertFunction(_location, "ASSERT %s -> " _format, #_condition, ##__VA_ARGS__) ) \ { \ bx::debugBreak(); \ } \ diff --git a/libs/bx/include/bx/math.h b/libs/bx/include/bx/math.h index c6e662a..a7b5e2b 100644 --- a/libs/bx/include/bx/math.h +++ b/libs/bx/include/bx/math.h @@ -203,6 +203,13 @@ namespace bx /// BX_CONSTEXPR_FUNC float square(float _a); + /// Returns the both sine and cosine of the argument _a. + /// + /// @remarks The function calculates cosine, and then approximates sine based on the cosine + /// result. Therefore calculation of sine is less accurate than calling `bx::sin` function. + /// + void sinCosApprox(float& _outSinApprox, float& _outCos, float _a); + /// Returns the sine of the argument _a. /// BX_CONST_FUNC float sin(float _a); diff --git a/libs/bx/include/bx/platform.h b/libs/bx/include/bx/platform.h index 07db220..abbd1c0 100644 --- a/libs/bx/include/bx/platform.h +++ b/libs/bx/include/bx/platform.h @@ -30,7 +30,6 @@ // C Runtime #define BX_CRT_BIONIC 0 -#define BX_CRT_BSD 0 #define BX_CRT_GLIBC 0 #define BX_CRT_LIBCXX 0 #define BX_CRT_MINGW 0 @@ -59,6 +58,7 @@ #define BX_PLATFORM_PS4 0 #define BX_PLATFORM_PS5 0 #define BX_PLATFORM_RPI 0 +#define BX_PLATFORM_VISIONOS 0 #define BX_PLATFORM_WINDOWS 0 #define BX_PLATFORM_WINRT 0 #define BX_PLATFORM_XBOXONE 0 @@ -196,6 +196,9 @@ || defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) # undef BX_PLATFORM_IOS # define BX_PLATFORM_IOS 1 +#elif defined(__has_builtin) && __has_builtin(__is_target_os) && __is_target_os(xros) +# undef BX_PLATFORM_VISIONOS +# define BX_PLATFORM_VISIONOS 1 #elif defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) # undef BX_PLATFORM_OSX # define BX_PLATFORM_OSX __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ @@ -232,33 +235,23 @@ # if defined(__BIONIC__) # undef BX_CRT_BIONIC # define BX_CRT_BIONIC 1 -# elif defined(_MSC_VER) -# undef BX_CRT_MSVC -# define BX_CRT_MSVC 1 # elif defined(__GLIBC__) # undef BX_CRT_GLIBC # define BX_CRT_GLIBC (__GLIBC__ * 10000 + __GLIBC_MINOR__ * 100) -# elif defined(__MINGW32__) || defined(__MINGW64__) +# elif defined(__MINGW32__) \ + || defined(__MINGW64__) # undef BX_CRT_MINGW # define BX_CRT_MINGW 1 -# elif defined(__apple_build_version__) || defined(__ORBIS__) || defined(__EMSCRIPTEN__) || defined(__llvm__) || defined(__HAIKU__) +# elif defined(_MSC_VER) +# undef BX_CRT_MSVC +# define BX_CRT_MSVC 1 +# elif defined(__apple_build_version__) \ + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_EMSCRIPTEN \ + || defined(__llvm__) # undef BX_CRT_LIBCXX # define BX_CRT_LIBCXX 1 -# elif BX_PLATFORM_BSD -# undef BX_CRT_BSD -# define BX_CRT_BSD 1 # endif // - -# if !BX_CRT_BIONIC \ - && !BX_CRT_BSD \ - && !BX_CRT_GLIBC \ - && !BX_CRT_LIBCXX \ - && !BX_CRT_MINGW \ - && !BX_CRT_MSVC \ - && !BX_CRT_NEWLIB -# undef BX_CRT_NONE -# define BX_CRT_NONE 1 -# endif // BX_CRT_* #endif // !BX_CRT_NONE /// @@ -275,6 +268,7 @@ || BX_PLATFORM_PS4 \ || BX_PLATFORM_PS5 \ || BX_PLATFORM_RPI \ + || BX_PLATFORM_VISIONOS \ ) /// @@ -291,6 +285,7 @@ || BX_PLATFORM_PS4 \ || BX_PLATFORM_PS5 \ || BX_PLATFORM_RPI \ + || BX_PLATFORM_VISIONOS \ || BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ || BX_PLATFORM_XBOXONE \ @@ -387,13 +382,15 @@ #elif BX_PLATFORM_NX # define BX_PLATFORM_NAME "NX" #elif BX_PLATFORM_OSX -# define BX_PLATFORM_NAME "OSX" +# define BX_PLATFORM_NAME "macOS" #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_VISIONOS +# define BX_PLATFORM_NAME "visionOS" #elif BX_PLATFORM_WINDOWS # define BX_PLATFORM_NAME "Windows" #elif BX_PLATFORM_WINRT @@ -420,8 +417,6 @@ #if BX_CRT_BIONIC # define BX_CRT_NAME "Bionic libc" -#elif BX_CRT_BSD -# define BX_CRT_NAME "BSD libc" #elif BX_CRT_GLIBC # define BX_CRT_NAME "GNU C Library" #elif BX_CRT_MSVC @@ -435,7 +430,7 @@ #elif BX_CRT_NONE # define BX_CRT_NAME "None" #else -# error "Unknown BX_CRT!" +# define BX_CRT_NAME "Unknown CRT" #endif // BX_CRT_ #if BX_ARCH_32BIT @@ -445,12 +440,12 @@ #endif // BX_ARCH_ #if defined(__cplusplus) -# if defined(_MSVC_LANG) && _MSVC_LANG != __cplusplus -# error "When using MSVC you must set /Zc:__cplusplus compiler option." -# endif // defined(_MSVC_LANG) && _MSVC_LANG != __cplusplus +# if BX_COMPILER_MSVC && defined(_MSVC_LANG) && _MSVC_LANG != __cplusplus +# error "When using MSVC you must set /Zc:__cplusplus compiler option." +# endif // BX_COMPILER_MSVC && defined(_MSVC_LANG) && _MSVC_LANG != __cplusplus # if __cplusplus < BX_LANGUAGE_CPP17 -# error "C++17 standard support is required to build." +# define BX_CPP_NAME "C++Unsupported" # elif __cplusplus < BX_LANGUAGE_CPP20 # define BX_CPP_NAME "C++17" # elif __cplusplus < BX_LANGUAGE_CPP23 @@ -463,23 +458,35 @@ # define BX_CPP_NAME "C++Unknown" #endif // defined(__cplusplus) -#if BX_PLATFORM_OSX && BX_PLATFORM_OSX < 130000 -//#error "Minimum supported macOS version is 13.00.\n" -#elif BX_PLATFORM_IOS && BX_PLATFORM_IOS < 160000 -//#error "Minimum supported macOS version is 16.00.\n" -#endif // BX_PLATFORM_OSX < 130000 +#if BX_COMPILER_MSVC && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) +# error "When using MSVC you must set /Zc:preprocessor compiler option." +#endif // BX_COMPILER_MSVC && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL) + +#if defined(__cplusplus) + +static_assert(__cplusplus >= BX_LANGUAGE_CPP17, "\n\n" + "\t** IMPORTANT! **\n\n" + "\tC++17 standard support is required to build.\n" + "\t\n"); + +// https://releases.llvm.org/ +static_assert(!BX_COMPILER_CLANG || BX_COMPILER_CLANG >= 110000, "\n\n" + "\t** IMPORTANT! **\n\n" + "\tMinimum supported Clang version is 11.0 (October 12, 2020).\n" + "\t\n"); -#if BX_CPU_ENDIAN_BIG -static_assert(false, "\n\n" +// https://gcc.gnu.org/releases.html +static_assert(!BX_COMPILER_GCC || BX_COMPILER_GCC >= 80400, "\n\n" + "\t** IMPORTANT! **\n\n" + "\tMinimum supported GCC version is 8.4 (March 4, 2020).\n" + "\t\n"); + +static_assert(!BX_CPU_ENDIAN_BIG, "\n\n" "\t** IMPORTANT! **\n\n" "\tThe code was not tested for big endian, and big endian CPU is considered unsupported.\n" "\t\n"); -#endif // BX_CPU_ENDIAN_BIG -#if BX_PLATFORM_BSD \ - || BX_PLATFORM_HAIKU \ - || BX_PLATFORM_HURD -static_assert(false, "\n\n" +static_assert(!BX_PLATFORM_BSD || !BX_PLATFORM_HAIKU || !BX_PLATFORM_HURD, "\n\n" "\t** IMPORTANT! **\n\n" "\tYou're compiling for unsupported platform!\n" "\tIf you wish to support this platform, make your own fork, and modify code for _yourself_.\n" @@ -488,6 +495,7 @@ static_assert(false, "\n\n" "\tto test on these platforms, and over years there wasn't any serious contributor who wanted to take\n" "\tburden of maintaining code for these platforms.\n" "\t\n"); -#endif // BX_PLATFORM_* + +#endif // defined(__cplusplus) #endif // BX_PLATFORM_H_HEADER_GUARD diff --git a/libs/bx/include/bx/simd_t.h b/libs/bx/include/bx/simd_t.h index a65e5ad..a0d129c 100644 --- a/libs/bx/include/bx/simd_t.h +++ b/libs/bx/include/bx/simd_t.h @@ -39,6 +39,7 @@ #elif BX_COMPILER_CLANG \ && !BX_PLATFORM_EMSCRIPTEN \ && !BX_PLATFORM_IOS \ + && !BX_PLATFORM_VISIONOS \ && BX_CLANG_HAS_EXTENSION(attribute_ext_vector_type) # undef BX_SIMD_LANGEXT # define BX_SIMD_LANGEXT 1 diff --git a/libs/bx/include/bx/thread.h b/libs/bx/include/bx/thread.h index f7db4af..79bdb09 100644 --- a/libs/bx/include/bx/thread.h +++ b/libs/bx/include/bx/thread.h @@ -72,6 +72,7 @@ namespace bx uint32_t m_stackSize; int32_t m_exitCode; bool m_running; + char m_name[64]; }; /// diff --git a/libs/bx/include/bx/typetraits.h b/libs/bx/include/bx/typetraits.h index 5510c85..9460000 100644 --- a/libs/bx/include/bx/typetraits.h +++ b/libs/bx/include/bx/typetraits.h @@ -165,6 +165,14 @@ namespace bx template constexpr bool isUnsigned(); + /// Returns value of `_t` as signed type value. + template + constexpr auto asSigned(Ty _value); + + /// Returns value of `_t` as unsigned type value. + template + constexpr auto asUnsigned(Ty _value); + /// Returns true if type `Ty` is integer type, otherwise returns false. template constexpr bool isInteger(); diff --git a/libs/bx/src/crtnone.cpp b/libs/bx/src/crtnone.cpp index 9bc0887..a06a09e 100644 --- a/libs/bx/src/crtnone.cpp +++ b/libs/bx/src/crtnone.cpp @@ -11,7 +11,7 @@ #if BX_CRT_NONE -#include "crt0.h" +#include #define NOT_IMPLEMENTED() \ { bx::debugPrintf("crtnone: %s not implemented\n", BX_FUNCTION); abort(); } @@ -511,6 +511,18 @@ extern "C" int prctl(int _option, unsigned long _arg2, unsigned long _arg3, unsi return -1; } +extern "C" int getpid() +{ + return crt0::processGetId(); +} + +extern "C" ssize_t readlink(const char* _pathName, char* _buffer, size_t _bufferSize) +{ + BX_UNUSED(_pathName, _buffer, _bufferSize); + NOT_IMPLEMENTED(); + return 0; +} + extern "C" int chdir(const char* _path) { BX_UNUSED(_path); @@ -635,6 +647,16 @@ void operator delete(void*, size_t) { } +extern "C" void* __cxa_begin_catch(void* _unwindArg) +{ + BX_UNUSED(_unwindArg); + return NULL; +} + +extern "C" void __cxa_end_catch() +{ +} + extern "C" void __cxa_pure_virtual(void) { } diff --git a/libs/bx/src/debug.cpp b/libs/bx/src/debug.cpp index 980724e..6d6cb0e 100644 --- a/libs/bx/src/debug.cpp +++ b/libs/bx/src/debug.cpp @@ -9,14 +9,14 @@ #include // PRIx* #if BX_CRT_NONE -# include "crt0.h" +# include #elif BX_PLATFORM_ANDROID # include #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ || BX_PLATFORM_XBOXONE extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char* _str); -#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX +#elif BX_PLATFORM_IOS || BX_PLATFORM_OSX || BX_PLATFORM_VISIONOS # if defined(__OBJC__) # import # else @@ -73,7 +73,8 @@ namespace bx || BX_PLATFORM_XBOXONE OutputDebugStringA(_out); #elif BX_PLATFORM_IOS \ - || BX_PLATFORM_OSX + || BX_PLATFORM_OSX \ + || BX_PLATFORM_VISIONOS # if defined(__OBJC__) NSLog(@"%s", _out); # else diff --git a/libs/bx/src/dtoa.cpp b/libs/bx/src/dtoa.cpp index 2498a9a..e65c2ff 100644 --- a/libs/bx/src/dtoa.cpp +++ b/libs/bx/src/dtoa.cpp @@ -8,8 +8,6 @@ #include #include -#include - namespace bx { /* @@ -481,12 +479,8 @@ namespace bx return 0; } - _max = toString(_dst + 1 - , _max - 1 - , typename std::make_unsigned::type(-_value) - , _base - , _separator - ); + _max = toString(_dst + 1, _max - 1, asUnsigned(-_value), _base, _separator); + if (_max == 0) { return 0; @@ -496,12 +490,7 @@ namespace bx return int32_t(_max + 1); } - return toString(_dst - , _max - , typename std::make_unsigned::type(_value) - , _base - , _separator - ); + return toString(_dst, _max, asUnsigned(_value), _base, _separator); } int32_t toString(char* _dst, int32_t _max, int32_t _value, uint32_t _base, char _separator) diff --git a/libs/bx/src/file.cpp b/libs/bx/src/file.cpp index e105f32..1ed80a0 100644 --- a/libs/bx/src/file.cpp +++ b/libs/bx/src/file.cpp @@ -14,7 +14,7 @@ #endif // BX_CONFIG_CRT_DIRECTORY_READER #if BX_CRT_NONE -# include "crt0.h" +# include #else # if BX_CONFIG_CRT_DIRECTORY_READER # include @@ -74,7 +74,8 @@ namespace bx || BX_PLATFORM_ANDROID \ || BX_PLATFORM_EMSCRIPTEN \ || BX_PLATFORM_IOS \ - || BX_PLATFORM_OSX + || BX_PLATFORM_OSX \ + || BX_PLATFORM_VISIONOS # define fseeko64 fseeko # define ftello64 ftello # elif BX_PLATFORM_PS4 @@ -799,7 +800,7 @@ namespace bx #if BX_CRT_MSVC int32_t result = ::_mkdir(_filePath.getCPtr() ); #elif BX_CRT_MINGW - int32_t result = ::mkdir(_filePath.getCPtr()); + int32_t result = ::mkdir(_filePath.getCPtr() ); #elif BX_CRT_NONE BX_UNUSED(_filePath); int32_t result = -1; diff --git a/libs/bx/src/filepath.cpp b/libs/bx/src/filepath.cpp index 32f7cdb..f18d40c 100644 --- a/libs/bx/src/filepath.cpp +++ b/libs/bx/src/filepath.cpp @@ -7,13 +7,11 @@ #include #include -#if !BX_CRT_NONE -# if BX_CRT_MSVC -# include // _getcwd -# else -# include // getcwd -# endif // BX_CRT_MSVC -#endif // !BX_CRT_NONE +#if BX_CRT_MSVC +# include // _getcwd +#else +# include // getcwd +#endif // BX_CRT_MSVC #if BX_PLATFORM_WINDOWS #if !defined(GetModuleFileName) diff --git a/libs/bx/src/mutex.cpp b/libs/bx/src/mutex.cpp index bb33109..a29134c 100644 --- a/libs/bx/src/mutex.cpp +++ b/libs/bx/src/mutex.cpp @@ -9,14 +9,15 @@ #if BX_CRT_NONE # include -# include "crt0.h" +# include #elif BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ || BX_PLATFORM_RPI \ - || BX_PLATFORM_NX + || BX_PLATFORM_NX \ + || BX_PLATFORM_VISIONOS # include #elif BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINRT \ diff --git a/libs/bx/src/os.cpp b/libs/bx/src/os.cpp index 97fad3d..c517bf2 100644 --- a/libs/bx/src/os.cpp +++ b/libs/bx/src/os.cpp @@ -26,11 +26,13 @@ || BX_PLATFORM_NX \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ - || BX_PLATFORM_RPI + || BX_PLATFORM_RPI \ + || BX_PLATFORM_VISIONOS # include // sched_yield # if BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ - || BX_PLATFORM_PS4 + || BX_PLATFORM_PS4 \ + || BX_PLATFORM_VISIONOS # include // mach_port_t # endif // BX_PLATFORM_* @@ -165,6 +167,7 @@ namespace bx || BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT \ + || BX_PLATFORM_NX \ || BX_CRT_NONE BX_UNUSED(_filePath); return NULL; @@ -188,6 +191,7 @@ namespace bx || BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT \ + || BX_PLATFORM_NX \ || BX_CRT_NONE BX_UNUSED(_handle); #else @@ -207,6 +211,7 @@ namespace bx || BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT \ + || BX_PLATFORM_NX \ || BX_CRT_NONE BX_UNUSED(_handle, symbol); return NULL; @@ -230,6 +235,7 @@ namespace bx || BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT \ + || BX_PLATFORM_NX \ || BX_CRT_NONE BX_UNUSED(name, _out, _inOutSize); return false; @@ -273,6 +279,7 @@ namespace bx || BX_PLATFORM_PS4 \ || BX_PLATFORM_XBOXONE \ || BX_PLATFORM_WINRT \ + || BX_PLATFORM_NX \ || BX_CRT_NONE BX_UNUSED(name, value); #else diff --git a/libs/bx/src/semaphore.cpp b/libs/bx/src/semaphore.cpp index 58511db..3525349 100644 --- a/libs/bx/src/semaphore.cpp +++ b/libs/bx/src/semaphore.cpp @@ -9,7 +9,8 @@ #if BX_CRT_NONE #elif BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS + || BX_PLATFORM_IOS \ + || BX_PLATFORM_VISIONOS # include #elif BX_PLATFORM_POSIX # include @@ -36,7 +37,8 @@ namespace bx #if BX_CRT_NONE #elif BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS + || BX_PLATFORM_IOS \ + || BX_PLATFORM_VISIONOS dispatch_semaphore_t m_handle; #elif BX_PLATFORM_POSIX pthread_mutex_t m_mutex; @@ -70,7 +72,8 @@ namespace bx return false; } #elif BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS + || BX_PLATFORM_IOS \ + || BX_PLATFORM_VISIONOS Semaphore::Semaphore() { diff --git a/libs/bx/src/string.cpp b/libs/bx/src/string.cpp index 290f897..0ba4be6 100644 --- a/libs/bx/src/string.cpp +++ b/libs/bx/src/string.cpp @@ -758,7 +758,7 @@ namespace bx len--; } - int32_t padding = _param.width > len ? _param.width - len - hasSign: 0; + const int32_t padding = _param.width > len ? _param.width - len - hasSign: 0; if (!_param.left) { @@ -769,7 +769,24 @@ namespace bx sign = '\0'; } - size += writeRep(_writer, _param.fill, max(0, padding), _err); + if (_param.width < _param.prec) + { + size += writeRep(_writer, _param.fill, max(0, padding), _err); + } + else + { + const int32_t maxPrec = max(_param.prec, len); + const int32_t fillLen = max(0, _param.width - maxPrec - hasSign); + size += writeRep(_writer, _param.fill, fillLen, _err); + + if ('\0' != sign) + { + size += write(_writer, sign, _err); + sign = '\0'; + } + + size += writeRep(_writer, '0', max(0, padding-fillLen), _err); + } } if ('\0' != sign) diff --git a/libs/bx/src/thread.cpp b/libs/bx/src/thread.cpp index 4aa7921..94cb2a4 100644 --- a/libs/bx/src/thread.cpp +++ b/libs/bx/src/thread.cpp @@ -13,14 +13,15 @@ #endif #if BX_CRT_NONE -# include "crt0.h" +# include #elif BX_PLATFORM_ANDROID \ || BX_PLATFORM_LINUX \ || BX_PLATFORM_IOS \ || BX_PLATFORM_OSX \ || BX_PLATFORM_PS4 \ || BX_PLATFORM_RPI \ - || BX_PLATFORM_NX + || BX_PLATFORM_NX \ + || BX_PLATFORM_VISIONOS # include # if BX_PLATFORM_LINUX && (BX_CRT_GLIBC < 21200) # include @@ -131,6 +132,16 @@ namespace bx m_userData = _userData; m_stackSize = _stackSize; + if (NULL != _name) + { + BX_WARN(strLen(_name) < int32_t(BX_COUNTOF(m_name) )-1, "Truncating thread name."); + strCopy(m_name, BX_COUNTOF(m_name), _name); + } + else + { + m_name[0] = '\0'; + } + ThreadInternal* ti = (ThreadInternal*)m_internal; #if BX_CRT_NONE ti->m_handle = crt0::threadCreate(&ti->threadFunc, _userData, m_stackSize, _name); @@ -189,11 +200,6 @@ namespace bx m_running = true; m_sem.wait(); - if (NULL != _name) - { - setThreadName(_name); - } - return true; } @@ -243,7 +249,8 @@ namespace bx #if BX_CRT_NONE BX_UNUSED(_name); #elif BX_PLATFORM_OSX \ - || BX_PLATFORM_IOS + || BX_PLATFORM_IOS \ + || BX_PLATFORM_VISIONOS pthread_setname_np(_name); #elif (BX_CRT_GLIBC >= 21200) pthread_setname_np(ti->m_handle, _name); @@ -314,6 +321,7 @@ namespace bx #endif // BX_PLATFORM_WINDOWS m_sem.post(); + setThreadName(m_name); int32_t result = m_fn(this, m_userData); return result; } diff --git a/libs/bx/src/timer.cpp b/libs/bx/src/timer.cpp index 4fcd042..57a873a 100644 --- a/libs/bx/src/timer.cpp +++ b/libs/bx/src/timer.cpp @@ -6,7 +6,7 @@ #include #if BX_CRT_NONE -# include "crt0.h" +# include #elif BX_PLATFORM_ANDROID # include // clock, clock_gettime #elif BX_PLATFORM_EMSCRIPTEN @@ -40,7 +40,7 @@ namespace bx int64_t i64 = int64_t(1000.0f * emscripten_get_now() ); #elif !BX_PLATFORM_NONE struct timeval now; - gettimeofday(&now, 0); + gettimeofday(&now, NULL); int64_t i64 = now.tv_sec*INT64_C(1000000) + now.tv_usec; #else BX_ASSERT(false, "Not implemented!"); diff --git a/shaders/bgfx_compute.sh b/shaders/bgfx_compute.sh index 9e8137f..d136004 100644 --- a/shaders/bgfx_compute.sh +++ b/shaders/bgfx_compute.sh @@ -32,22 +32,22 @@ #define readwrite #define IMAGE2D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readonly) #define UIMAGE2D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readonly) -#define IMAGE2D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, writeonly) -#define UIMAGE2D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, writeonly) +#define IMAGE2D_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, writeonly) +#define UIMAGE2D_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, writeonly) #define IMAGE2D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2D, readwrite) #define UIMAGE2D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2D, readwrite) #define IMAGE2D_ARRAY_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readonly) #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readonly) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, writeonly) -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, writeonly) +#define IMAGE2D_ARRAY_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, writeonly) +#define UIMAGE2D_ARRAY_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, writeonly) #define IMAGE2D_ARRAY_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image2DArray, readwrite) #define UIMAGE2D_ARRAY_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage2DArray, readwrite) #define IMAGE3D_RO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readonly) #define UIMAGE3D_RO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readonly) -#define IMAGE3D_WR( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, writeonly) -#define UIMAGE3D_WR(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, writeonly) +#define IMAGE3D_WO( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, writeonly) +#define UIMAGE3D_WO(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, writeonly) #define IMAGE3D_RW( _name, _format, _reg) __IMAGE_XX(_name, _format, _reg, image3D, readwrite) #define UIMAGE3D_RW(_name, _format, _reg) __IMAGE_XX(_name, _format, _reg, uimage3D, readwrite) @@ -59,7 +59,7 @@ #define BUFFER_RO(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readonly) #define BUFFER_RW(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, readwrite) -#define BUFFER_WR(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, writeonly) +#define BUFFER_WO(_name, _type, _reg) __BUFFER_XX(_name, _type, _reg, writeonly) #define NUM_THREADS(_x, _y, _z) layout (local_size_x = _x, local_size_y = _y, local_size_z = _z) in; @@ -99,10 +99,10 @@ #define UIMAGE2D_RO(_name, _format, _reg) IMAGE2D_RO(_name, _format, _reg) -#define IMAGE2D_WR( _name, _format, _reg) \ +#define IMAGE2D_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ -#define UIMAGE2D_WR(_name, _format, _reg) IMAGE2D_WR(_name, _format, _reg) +#define UIMAGE2D_WO(_name, _format, _reg) IMAGE2D_WO(_name, _format, _reg) #define IMAGE2D_RW( _name, _format, _reg) \ FORMAT(_format) RWTexture2D _name : REGISTER(u, _reg); \ @@ -114,10 +114,10 @@ #define UIMAGE2D_ARRAY_RO(_name, _format, _reg) IMAGE2D_ARRAY_RO(_name, _format, _reg) -#define IMAGE2D_ARRAY_WR( _name, _format, _reg) \ +#define IMAGE2D_ARRAY_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ -#define UIMAGE2D_ARRAY_WR(_name, _format, _reg) IMAGE2D_ARRAY_WR(_name, _format, _reg) +#define UIMAGE2D_ARRAY_WO(_name, _format, _reg) IMAGE2D_ARRAY_WO(_name, _format, _reg) #define IMAGE2D_ARRAY_RW(_name, _format, _reg) \ FORMAT(_format) RWTexture2DArray _name : REGISTER(u, _reg); \ @@ -129,10 +129,10 @@ #define UIMAGE3D_RO(_name, _format, _reg) IMAGE3D_RO(_name, _format, _reg) -#define IMAGE3D_WR( _name, _format, _reg) \ +#define IMAGE3D_WO( _name, _format, _reg) \ WRITEONLY FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); -#define UIMAGE3D_WR(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) +#define UIMAGE3D_WO(_name, _format, _reg) IMAGE3D_RW(_name, _format, _reg) #define IMAGE3D_RW( _name, _format, _reg) \ FORMAT(_format) RWTexture3D _name : REGISTER(u, _reg); \ @@ -142,11 +142,11 @@ #if BGFX_SHADER_LANGUAGE_METAL || BGFX_SHADER_LANGUAGE_SPIRV #define BUFFER_RO(_name, _struct, _reg) StructuredBuffer<_struct> _name : REGISTER(t, _reg) #define BUFFER_RW(_name, _struct, _reg) RWStructuredBuffer <_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) +#define BUFFER_WO(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) #else #define BUFFER_RO(_name, _struct, _reg) Buffer<_struct> _name : REGISTER(t, _reg) #define BUFFER_RW(_name, _struct, _reg) RWBuffer<_struct> _name : REGISTER(u, _reg) -#define BUFFER_WR(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) +#define BUFFER_WO(_name, _struct, _reg) BUFFER_RW(_name, _struct, _reg) #endif #define NUM_THREADS(_x, _y, _z) [numthreads(_x, _y, _z)] diff --git a/src/zbgfx.cpp b/src/zbgfx.cpp index 0b243b2..43ee25a 100644 --- a/src/zbgfx.cpp +++ b/src/zbgfx.cpp @@ -255,33 +255,39 @@ extern "C" } /// - void zbgfx_EncoderDrawQuad(DebugDrawEncoder *dde, float _normal[3], float _center[3], float _size) { + void zbgfx_EncoderDrawQuad(DebugDrawEncoder *dde, float _normal[3], float _center[3], float _size) + { dde->drawQuad(*(bx::Vec3 *)(_normal), *(bx::Vec3 *)(_center), _size); } /// - void zbgfx_EncoderDrawQuadSprite(DebugDrawEncoder *dde, SpriteHandle _handle, float _normal[3],float _center[3], float _size) { + void zbgfx_EncoderDrawQuadSprite(DebugDrawEncoder *dde, SpriteHandle _handle, float _normal[3], float _center[3], float _size) + { dde->drawQuad(_handle, *(bx::Vec3 *)(_normal), *(bx::Vec3 *)(_center), _size); } /// - void zbgfx_EncoderDrawQuadTexture(DebugDrawEncoder *dde, bgfx::TextureHandle _handle, float _normal[3],float _center[3], float _size) { + void zbgfx_EncoderDrawQuadTexture(DebugDrawEncoder *dde, bgfx::TextureHandle _handle, float _normal[3], float _center[3], float _size) + { dde->drawQuad(_handle, *(bx::Vec3 *)(_normal), *(bx::Vec3 *)(_center), _size); } /// - void zbgfx_EncoderDrawAxis(DebugDrawEncoder *dde, float _x, float _y, float _z, float _len = 1.0f, Axis::Enum _highlight = Axis::Count, float _thickness = 0.0f) { + void zbgfx_EncoderDrawAxis(DebugDrawEncoder *dde, float _x, float _y, float _z, float _len = 1.0f, Axis::Enum _highlight = Axis::Count, float _thickness = 0.0f) + { dde->drawAxis(_x, _y, _z, _len, _highlight, _thickness); } /// - void zbgfx_EncoderDrawGrid(DebugDrawEncoder *dde, float _normal[3], float _center[3], uint32_t _size = 20, float _step = 1.0f) { - dde->drawGrid( *(bx::Vec3 *)(_normal), *(bx::Vec3 *)(_center), _size, _step); + void zbgfx_EncoderDrawGrid(DebugDrawEncoder *dde, float _normal[3], float _center[3], uint32_t _size = 20, float _step = 1.0f) + { + dde->drawGrid(*(bx::Vec3 *)(_normal), *(bx::Vec3 *)(_center), _size, _step); } /// - void zbgfx_EncoderDrawGridAxis(DebugDrawEncoder *dde, Axis::Enum _axis, float _center[3], uint32_t _size = 20, float _step = 1.0f) { - dde->drawGrid( _axis, *(bx::Vec3 *)(_center), _size, _step); + void zbgfx_EncoderDrawGridAxis(DebugDrawEncoder *dde, Axis::Enum _axis, float _center[3], uint32_t _size = 20, float _step = 1.0f) + { + dde->drawGrid(_axis, *(bx::Vec3 *)(_center), _size, _step); } ///